Compare commits

...
7 changed files with 42 additions and 41 deletions

View file

@ -6,15 +6,17 @@ using SQLite;
namespace ModuleCore.Git; namespace ModuleCore.Git;
// TODO: better name for this /// <summary>
public class GitManager /// Manages git repo registration, including creating any registration persistence via a backing <see cref="DatabaseManager"/>
/// </summary>
public class GitRepoRegistrationManager
{ {
private static readonly Lazy<GitManager> GitManagerInstance = new(() => new GitManager()); private static readonly Lazy<GitRepoRegistrationManager> GitManagerInstance = new(() => new GitRepoRegistrationManager());
private static Action<string>? _debugWriterDelegate; private static Action<string>? _debugWriterDelegate;
private readonly DatabaseManager _db; private readonly DatabaseManager _db;
private readonly ConcurrentDictionary<string, InternalGitRegistration> _registrations; private readonly ConcurrentDictionary<string, InternalGitRegistration> _registrations;
private GitManager(string? databaseName = null) private GitRepoRegistrationManager(string? databaseName = null)
{ {
_registrations = new ConcurrentDictionary<string, InternalGitRegistration>(); _registrations = new ConcurrentDictionary<string, InternalGitRegistration>();
// Regular usage of this constructor will never pass a database name in. Currently only tests should be hitting // Regular usage of this constructor will never pass a database name in. Currently only tests should be hitting
@ -25,15 +27,15 @@ public class GitManager
} }
/// <summary> /// <summary>
/// Returns the current <see cref="GitManager"/> instance. If no instance has been created, returns a new instance /// Returns the current <see cref="GitRepoRegistrationManager"/> instance. If no instance has been created, returns a new instance
/// and then the same instance every call after. /// and then the same instance every call after.
/// </summary> /// </summary>
public static GitManager Instance => GitManagerInstance.Value; public static GitRepoRegistrationManager Instance => GitManagerInstance.Value;
/// <summary> /// <summary>
/// Always returns a new clean instance of GitManager /// Always returns a new clean instance of GitManager
/// </summary> /// </summary>
internal static GitManager InternalFreshInstance(string databaseName) => new(databaseName); internal static GitRepoRegistrationManager InternalFreshInstance(string databaseName) => new(databaseName);
/// <summary> /// <summary>
/// Deletes the underlying database file. /// Deletes the underlying database file.
@ -388,20 +390,4 @@ public class GitManager
return _currentBranch.Trim(); return _currentBranch.Trim();
} }
} }
}
/// <summary>
/// The directory details of the directory returned from git rev-parse --show-toplevel
/// </summary>
public class ParsedGitFolderDetails
{
/// <summary>
/// The full path to the top level folder containing a git repository
/// </summary>
public string Directory { get; init; } = null!;
/// <summary>
/// The last folder name of the directory
/// </summary>
public string Folder { get; init; } = null!;
} }

View file

@ -0,0 +1,17 @@
namespace ModuleCore.Git.Models;
/// <summary>
/// The directory details of the directory returned from git rev-parse --show-toplevel
/// </summary>
public class ParsedGitFolderDetails
{
/// <summary>
/// The full path to the top level folder containing a git repository
/// </summary>
public string Directory { get; init; } = null!;
/// <summary>
/// The last folder name of the directory
/// </summary>
public string Folder { get; init; } = null!;
}

View file

@ -13,7 +13,7 @@ public class GetGitRepoRegistrationCommand : PSCmdlet
{ {
protected override void BeginProcessing() protected override void BeginProcessing()
{ {
var repos = GitManager.Instance.ListRepos(); var repos = GitRepoRegistrationManager.Instance.ListRepos();
WriteObject(repos); WriteObject(repos);

View file

@ -17,19 +17,19 @@ public sealed class NewGitRepoRegistrationCommand : PSCmdlet
{ {
try try
{ {
GitManager.SetDebugWriter(WriteDebug); GitRepoRegistrationManager.SetDebugWriter(WriteDebug);
// Test that we're in a git repo first. If we aren't (or git isn't available), this method will throw // Test that we're in a git repo first. If we aren't (or git isn't available), this method will throw
// so we don't need to handle for null (yet). // so we don't need to handle for null (yet).
var repoFolder = GitManager.IsGitRepo(SessionState.Path.CurrentLocation.Path); var repoFolder = GitRepoRegistrationManager.IsGitRepo(SessionState.Path.CurrentLocation.Path);
if (string.IsNullOrWhiteSpace(Name)) if (string.IsNullOrWhiteSpace(Name))
{ {
WriteDebug("No name given for registration, defaulting to git folder root."); WriteDebug("No name given for registration, defaulting to git folder root.");
} }
GitManager.Instance.RegisterRepo(repoFolder.Directory, Name ?? repoFolder.Folder); GitRepoRegistrationManager.Instance.RegisterRepo(repoFolder.Directory, Name ?? repoFolder.Folder);
GitManager.ClearDebugWriter(); GitRepoRegistrationManager.ClearDebugWriter();
base.BeginProcessing(); base.BeginProcessing();
} }

View file

@ -17,21 +17,21 @@ public class RemoveGitRepoRegistrationCommand : PSCmdlet
{ {
try try
{ {
GitManager.SetDebugWriter(WriteDebug); GitRepoRegistrationManager.SetDebugWriter(WriteDebug);
// If we aren't given a value for the Name argument, default behaviour is to attempt to remove a registration // If we aren't given a value for the Name argument, default behaviour is to attempt to remove a registration
// by the current git repo folder name for the current location. // by the current git repo folder name for the current location.
// If we have a name, don't bother testing for a git repo, just attempt to remove the registration by name // If we have a name, don't bother testing for a git repo, just attempt to remove the registration by name
// regardless of where we're being called from // regardless of where we're being called from
var registrationNameToRemove = string.IsNullOrEmpty(Name) var registrationNameToRemove = string.IsNullOrEmpty(Name)
? GitManager.IsGitRepo(SessionState.Path.CurrentLocation.Path).Folder ? GitRepoRegistrationManager.IsGitRepo(SessionState.Path.CurrentLocation.Path).Folder
: Name; : Name;
GitManager.Instance.UnregisterRepo(registrationNameToRemove); GitRepoRegistrationManager.Instance.UnregisterRepo(registrationNameToRemove);
// Removing a registration works similar to registering a new one - we either remove by exact name, or by // Removing a registration works similar to registering a new one - we either remove by exact name, or by
// the folder if no name is given (so a user can remove a registration from a git repo they're currently in) // the folder if no name is given (so a user can remove a registration from a git repo they're currently in)
GitManager.ClearDebugWriter(); GitRepoRegistrationManager.ClearDebugWriter();
base.BeginProcessing(); base.BeginProcessing();
} }

View file

@ -21,7 +21,7 @@ public class ShowGitRepoRegistrationCommand : PSCmdlet
protected override void BeginProcessing() protected override void BeginProcessing()
{ {
var location = GitManager.Instance.GetDirectoryForRegisteredRepo(Name); var location = GitRepoRegistrationManager.Instance.GetDirectoryForRegisteredRepo(Name);
// By default instead of doing the same as cd, we instead do pushd so a user can popd straight back to where // By default instead of doing the same as cd, we instead do pushd so a user can popd straight back to where
// they came from. // they came from.

View file

@ -23,7 +23,7 @@ public class AddRegistrationTests
public Task BasicRepoRegistration((int testId, string path) testData) public Task BasicRepoRegistration((int testId, string path) testData)
{ {
Settings.UseFileName($"{nameof(BasicRepoRegistration)}_{testData.testId}"); Settings.UseFileName($"{nameof(BasicRepoRegistration)}_{testData.testId}");
var gitManager = GitManager.InternalFreshInstance(nameof(BasicRepoRegistration)); var gitManager = GitRepoRegistrationManager.InternalFreshInstance(nameof(BasicRepoRegistration));
try try
{ {
@ -44,7 +44,7 @@ public class AddRegistrationTests
public void RepoRegistrationWithEmptyName() public void RepoRegistrationWithEmptyName()
{ {
Settings.UseFileName(nameof(RepoRegistrationWithEmptyName)); Settings.UseFileName(nameof(RepoRegistrationWithEmptyName));
var gitManager = GitManager.InternalFreshInstance(nameof(RepoRegistrationWithEmptyName)); var gitManager = GitRepoRegistrationManager.InternalFreshInstance(nameof(RepoRegistrationWithEmptyName));
var testRepoAbsolutePath = "Test:/some/test/repo"; var testRepoAbsolutePath = "Test:/some/test/repo";
try try
@ -63,7 +63,7 @@ public class AddRegistrationTests
public void RepoRegistrationWithNullName() public void RepoRegistrationWithNullName()
{ {
Settings.UseFileName(nameof(RepoRegistrationWithNullName)); Settings.UseFileName(nameof(RepoRegistrationWithNullName));
var gitManager = GitManager.InternalFreshInstance(nameof(RepoRegistrationWithNullName)); var gitManager = GitRepoRegistrationManager.InternalFreshInstance(nameof(RepoRegistrationWithNullName));
var testRepoAbsolutePath = "Test:/some/test/repo"; var testRepoAbsolutePath = "Test:/some/test/repo";
try try
{ {
@ -84,7 +84,7 @@ public class AddRegistrationTests
{ {
Settings.UseFileName(nameof(RepoRegistrationWithWhitespaceName)); Settings.UseFileName(nameof(RepoRegistrationWithWhitespaceName));
var gitManager = GitManager.InternalFreshInstance(nameof(RepoRegistrationWithWhitespaceName)); var gitManager = GitRepoRegistrationManager.InternalFreshInstance(nameof(RepoRegistrationWithWhitespaceName));
var testRepoAbsolutePath = "Test:/some/test/repo"; var testRepoAbsolutePath = "Test:/some/test/repo";
try try
{ {
@ -102,7 +102,7 @@ public class AddRegistrationTests
public void DuplicateRepoRegistrationShouldFail() public void DuplicateRepoRegistrationShouldFail()
{ {
Settings.UseFileName(nameof(RepoRegistrationWithWhitespaceName)); Settings.UseFileName(nameof(RepoRegistrationWithWhitespaceName));
var gitManager = GitManager.InternalFreshInstance(nameof(RepoRegistrationWithWhitespaceName)); var gitManager = GitRepoRegistrationManager.InternalFreshInstance(nameof(RepoRegistrationWithWhitespaceName));
var testRepoAbsolutePath = "Test:/some/test/repo"; var testRepoAbsolutePath = "Test:/some/test/repo";
string[] paths = ["test", "nested", "path"]; string[] paths = ["test", "nested", "path"];
var names = (NormalSeparator: string.Join(Path.DirectorySeparatorChar, paths), AltSeparator: string.Join(Path.AltDirectorySeparatorChar, paths)); var names = (NormalSeparator: string.Join(Path.DirectorySeparatorChar, paths), AltSeparator: string.Join(Path.AltDirectorySeparatorChar, paths));
@ -110,7 +110,6 @@ public class AddRegistrationTests
try try
{ {
var firstRegistration = gitManager.RegisterRepo(testRepoAbsolutePath, names.NormalSeparator); var firstRegistration = gitManager.RegisterRepo(testRepoAbsolutePath, names.NormalSeparator);
// TODO: make nested registrations fail in both directions and test
var secondRegistration = gitManager.RegisterRepo(testRepoAbsolutePath, Path.Combine(paths[..1])); var secondRegistration = gitManager.RegisterRepo(testRepoAbsolutePath, Path.Combine(paths[..1]));
Assert.Equal(Path.Combine(paths), firstRegistration); Assert.Equal(Path.Combine(paths), firstRegistration);
@ -128,7 +127,7 @@ public class AddRegistrationTests
public void DuplicateRepoRegistrationDifferentSlashShouldNotFail() public void DuplicateRepoRegistrationDifferentSlashShouldNotFail()
{ {
Settings.UseFileName(nameof(RepoRegistrationWithWhitespaceName)); Settings.UseFileName(nameof(RepoRegistrationWithWhitespaceName));
var gitManager = GitManager.InternalFreshInstance(nameof(RepoRegistrationWithWhitespaceName)); var gitManager = GitRepoRegistrationManager.InternalFreshInstance(nameof(RepoRegistrationWithWhitespaceName));
var testRepoAbsolutePath = "Test:/some/test/repo"; var testRepoAbsolutePath = "Test:/some/test/repo";
string[] paths = ["test", "nested", "path"]; string[] paths = ["test", "nested", "path"];
var names = (NormalSeparator: string.Join(Path.DirectorySeparatorChar, paths), AltSeparator: string.Join(Path.AltDirectorySeparatorChar, paths)); var names = (NormalSeparator: string.Join(Path.DirectorySeparatorChar, paths), AltSeparator: string.Join(Path.AltDirectorySeparatorChar, paths));
@ -136,7 +135,6 @@ public class AddRegistrationTests
try try
{ {
var firstRegistration = gitManager.RegisterRepo(testRepoAbsolutePath, names.NormalSeparator); var firstRegistration = gitManager.RegisterRepo(testRepoAbsolutePath, names.NormalSeparator);
// TODO: make nested registrations fail in both directions and test
var secondRegistration = gitManager.RegisterRepo(testRepoAbsolutePath, Path.Combine(paths[..1])); var secondRegistration = gitManager.RegisterRepo(testRepoAbsolutePath, Path.Combine(paths[..1]));
var differentPathSeparatorRegistration = gitManager.RegisterRepo(testRepoAbsolutePath, names.AltSeparator); var differentPathSeparatorRegistration = gitManager.RegisterRepo(testRepoAbsolutePath, names.AltSeparator);