Compare commits

..
7 changed files with 41 additions and 42 deletions

View file

@ -6,17 +6,15 @@ using SQLite;
namespace ModuleCore.Git; namespace ModuleCore.Git;
/// <summary> // TODO: better name for this
/// Manages git repo registration, including creating any registration persistence via a backing <see cref="DatabaseManager"/> public class GitManager
/// </summary>
public class GitRepoRegistrationManager
{ {
private static readonly Lazy<GitRepoRegistrationManager> GitManagerInstance = new(() => new GitRepoRegistrationManager()); private static readonly Lazy<GitManager> GitManagerInstance = new(() => new GitManager());
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 GitRepoRegistrationManager(string? databaseName = null) private GitManager(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
@ -27,15 +25,15 @@ public class GitRepoRegistrationManager
} }
/// <summary> /// <summary>
/// Returns the current <see cref="GitRepoRegistrationManager"/> instance. If no instance has been created, returns a new instance /// Returns the current <see cref="GitManager"/> 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 GitRepoRegistrationManager Instance => GitManagerInstance.Value; public static GitManager 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 GitRepoRegistrationManager InternalFreshInstance(string databaseName) => new(databaseName); internal static GitManager InternalFreshInstance(string databaseName) => new(databaseName);
/// <summary> /// <summary>
/// Deletes the underlying database file. /// Deletes the underlying database file.
@ -391,3 +389,19 @@ public class GitRepoRegistrationManager
} }
} }
} }
/// <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

@ -1,17 +0,0 @@
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 = GitRepoRegistrationManager.Instance.ListRepos(); var repos = GitManager.Instance.ListRepos();
WriteObject(repos); WriteObject(repos);

View file

@ -17,19 +17,19 @@ public sealed class NewGitRepoRegistrationCommand : PSCmdlet
{ {
try try
{ {
GitRepoRegistrationManager.SetDebugWriter(WriteDebug); GitManager.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 = GitRepoRegistrationManager.IsGitRepo(SessionState.Path.CurrentLocation.Path); var repoFolder = GitManager.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.");
} }
GitRepoRegistrationManager.Instance.RegisterRepo(repoFolder.Directory, Name ?? repoFolder.Folder); GitManager.Instance.RegisterRepo(repoFolder.Directory, Name ?? repoFolder.Folder);
GitRepoRegistrationManager.ClearDebugWriter(); GitManager.ClearDebugWriter();
base.BeginProcessing(); base.BeginProcessing();
} }

View file

@ -17,21 +17,21 @@ public class RemoveGitRepoRegistrationCommand : PSCmdlet
{ {
try try
{ {
GitRepoRegistrationManager.SetDebugWriter(WriteDebug); GitManager.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)
? GitRepoRegistrationManager.IsGitRepo(SessionState.Path.CurrentLocation.Path).Folder ? GitManager.IsGitRepo(SessionState.Path.CurrentLocation.Path).Folder
: Name; : Name;
GitRepoRegistrationManager.Instance.UnregisterRepo(registrationNameToRemove); GitManager.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)
GitRepoRegistrationManager.ClearDebugWriter(); GitManager.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 = GitRepoRegistrationManager.Instance.GetDirectoryForRegisteredRepo(Name); var location = GitManager.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 = GitRepoRegistrationManager.InternalFreshInstance(nameof(BasicRepoRegistration)); var gitManager = GitManager.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 = GitRepoRegistrationManager.InternalFreshInstance(nameof(RepoRegistrationWithEmptyName)); var gitManager = GitManager.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 = GitRepoRegistrationManager.InternalFreshInstance(nameof(RepoRegistrationWithNullName)); var gitManager = GitManager.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 = GitRepoRegistrationManager.InternalFreshInstance(nameof(RepoRegistrationWithWhitespaceName)); var gitManager = GitManager.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 = GitRepoRegistrationManager.InternalFreshInstance(nameof(RepoRegistrationWithWhitespaceName)); var gitManager = GitManager.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,6 +110,7 @@ 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);
@ -127,7 +128,7 @@ public class AddRegistrationTests
public void DuplicateRepoRegistrationDifferentSlashShouldNotFail() public void DuplicateRepoRegistrationDifferentSlashShouldNotFail()
{ {
Settings.UseFileName(nameof(RepoRegistrationWithWhitespaceName)); Settings.UseFileName(nameof(RepoRegistrationWithWhitespaceName));
var gitManager = GitRepoRegistrationManager.InternalFreshInstance(nameof(RepoRegistrationWithWhitespaceName)); var gitManager = GitManager.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));
@ -135,6 +136,7 @@ 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);