diff --git a/src/ModuleCore/Git/GitManager.cs b/src/ModuleCore/Git/GitManager.cs index 702d0e1..14b58db 100644 --- a/src/ModuleCore/Git/GitManager.cs +++ b/src/ModuleCore/Git/GitManager.cs @@ -1,4 +1,5 @@ using System.Collections.Concurrent; +using System.Diagnostics; namespace ModuleCore.Git; @@ -17,13 +18,67 @@ public class GitManager { public required string Name { get; set; } public required string Location { get; set; } + public string CurrentBranch => GetCurrentBranch(); + + private string _currentBranch = string.Empty; + private long _nextCheckTime; + + // TODO: not fully decided on if I want this feature or not, but keeping it in for now + private string GetCurrentBranch() + { + var now = DateTime.Now; + // git branch should be quick enough that even with a large number of registrations this shouldn't be that slow + // when doing Get-GitRepo, but regardless we still only get the current branch via git if it's been some amount + // of time since the last time we did. + if (now.Ticks < _nextCheckTime) + { + return _currentBranch; + } + + // use -C for the git command so we don't need to set the working directory and the git command can be run + // from anywhere against the appropriate location + var ps = new ProcessStartInfo("git", + ["-C", Location, "branch", "--show-current"]) + { + RedirectStandardOutput = true, + RedirectStandardError = true, + }; + + // If the user doesn't have git on their path, this will throw an exception that I don't have to do anything + // special with, it'll be unhandled and powershell will handle it + var gitProcess = Process.Start(ps); + + // This probably shouldn't be possible? Not really sure of the conditions where the process could be started + // but return null, but I'm going to consider that unrecoverable error territory + if (gitProcess is null) + { + throw new Exception("git failed to start"); + } + + gitProcess.WaitForExit(); + + if (!gitProcess.StandardOutput.EndOfStream) + { + _currentBranch = gitProcess.StandardOutput.ReadToEnd(); + } + + if (!gitProcess.StandardError.EndOfStream) + { + _currentBranch = gitProcess.StandardError.ReadToEnd(); + } + + // Set the next check to be in the future so we don't hold up any list commands every time. + _nextCheckTime = now.AddMinutes(15).Ticks; + + return _currentBranch; + } } private readonly ConcurrentDictionary _registrations; private GitManager() { - Console.WriteLine($"{nameof(GitManager)} init"); + Debug.WriteLine($"{nameof(GitManager)} init"); _registrations = new ConcurrentDictionary(); } @@ -55,7 +110,7 @@ public class GitManager public List ListRepos() { - return _registrations.Select(x => new GitReg() { Name = x.Value.Name, Location = x.Value.Location }).ToList(); + return _registrations.Select(x => new GitReg() { Name = x.Value.Name, Location = x.Value.Location, CurrentBranch = x.Value.CurrentBranch }).ToList(); } public string GetRepo(string? registeredName) @@ -78,4 +133,5 @@ public class GitReg { public required string Name { get; set; } public required string Location { get; set; } + public required string CurrentBranch { get; set; } } \ No newline at end of file diff --git a/src/PowershellModule/Git/Commands/NewGitRepoCommand.cs b/src/PowershellModule/Git/Commands/NewGitRepoCommand.cs index 4078837..103cffa 100644 --- a/src/PowershellModule/Git/Commands/NewGitRepoCommand.cs +++ b/src/PowershellModule/Git/Commands/NewGitRepoCommand.cs @@ -101,11 +101,11 @@ public sealed class NewGitRepoCommand : PSCmdlet /// /// The full path to the top level folder containing a git repository /// - public string Directory { get; set; } = null!; + public string Directory { get; init; } = null!; /// /// The last folder name of the directory /// - public string Folder { get; set; } = null!; + public string Folder { get; init; } = null!; } } \ No newline at end of file diff --git a/src/PowershellModule/Git/Commands/ShowGitRepoCommand.cs b/src/PowershellModule/Git/Commands/ShowGitRepoCommand.cs index 3394ef3..6ff7909 100644 --- a/src/PowershellModule/Git/Commands/ShowGitRepoCommand.cs +++ b/src/PowershellModule/Git/Commands/ShowGitRepoCommand.cs @@ -4,6 +4,10 @@ using ModuleCore.Git; namespace PowershellModule.Git.Commands; +// TODO: decide on if I like Show to be used as the verb name. Other options I have are push/pop and open. +// Seeing as this is likely just for me currently, Show-GitRepo suits my workflow more where I'll want to quickly just +// pushd into a git repo, do whatever I want to do with it/change directories in it whatever, and then popd at the end. +// I'll also be integrating the current stack into the custom prompt whenever I get around to doing that [Cmdlet(VerbsCommon.Show, GitCommands.GitRepoNoun)] public class ShowGitRepoCommand : PSCmdlet {