refactor(git-provider): move IsGitRepo to GitManager, refactor NewGitRepoCommand
This commit is contained in:
parent
c48549117f
commit
cf446fc5dc
2 changed files with 91 additions and 82 deletions
|
|
@ -145,6 +145,73 @@ public class GitManager
|
||||||
throw new Exception($"No git repo has been registered with the name {registeredName}");
|
throw new Exception($"No git repo has been registered with the name {registeredName}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the git root directory for any nested directory if git rev-parse --show-toplevel returns a value.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">Path to check if it or any of its parents contain a git repository</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
/// <exception cref="Exception">
|
||||||
|
/// Git fails to start, returns an error (ie: the directory is not in a git repo), or the git process does not return
|
||||||
|
/// any output or error.
|
||||||
|
/// </exception>
|
||||||
|
public static ParsedGitFolderDetails IsGitRepo(string path)
|
||||||
|
{
|
||||||
|
_debugWriterDelegate?.Invoke("Checking if current directory is a git repository...");
|
||||||
|
|
||||||
|
var ps = new ProcessStartInfo("git",
|
||||||
|
["-C", path, "rev-parse", "--show-toplevel"])
|
||||||
|
{
|
||||||
|
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")
|
||||||
|
{
|
||||||
|
Source = "git-process",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
gitProcess.WaitForExit();
|
||||||
|
|
||||||
|
if (!gitProcess.StandardOutput.EndOfStream)
|
||||||
|
{
|
||||||
|
var directory = gitProcess.StandardOutput.ReadToEnd();
|
||||||
|
// Gotta trim what we get as it might already have a newline character at the end
|
||||||
|
var dirInfo = new DirectoryInfo(directory.Trim());
|
||||||
|
|
||||||
|
_debugWriterDelegate?.Invoke("...location is a git repo (duh).");
|
||||||
|
|
||||||
|
var repoFolderInfo = new ParsedGitFolderDetails
|
||||||
|
{
|
||||||
|
Directory = dirInfo.FullName,
|
||||||
|
Folder = dirInfo.Name,
|
||||||
|
};
|
||||||
|
|
||||||
|
return repoFolderInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gitProcess.StandardError.EndOfStream)
|
||||||
|
{
|
||||||
|
throw new Exception(gitProcess.StandardError.ReadToEnd())
|
||||||
|
{
|
||||||
|
Source = "git-not-found",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Exception("Unable to determine if directory is repository: git command returned no output or errors.")
|
||||||
|
{
|
||||||
|
Source = "git-parse-failed",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Registers an output for debug output. <see cref="ClearDebugWriter" /> should be called as soon as the need for output
|
/// Registers an output for debug output. <see cref="ClearDebugWriter" /> should be called as soon as the need for output
|
||||||
/// is no longer needed.
|
/// is no longer needed.
|
||||||
|
|
@ -235,3 +302,19 @@ public class GitManager
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <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!;
|
||||||
|
}
|
||||||
|
|
@ -17,95 +17,21 @@ public sealed class NewGitRepoCommand : PSCmdlet
|
||||||
|
|
||||||
protected override void BeginProcessing()
|
protected override void BeginProcessing()
|
||||||
{
|
{
|
||||||
GitManager.SetDebugWriter(WriteDebug);
|
try
|
||||||
|
|
||||||
var repoFolder = IsGitRepo(SessionState.Path.CurrentLocation.Path);
|
|
||||||
|
|
||||||
if (repoFolder is not null)
|
|
||||||
{
|
{
|
||||||
|
GitManager.SetDebugWriter(WriteDebug);
|
||||||
|
|
||||||
|
var repoFolder = GitManager.IsGitRepo(SessionState.Path.CurrentLocation.Path);
|
||||||
|
|
||||||
GitManager.Instance.RegisterRepo(repoFolder.Directory, Name ?? repoFolder.Folder);
|
GitManager.Instance.RegisterRepo(repoFolder.Directory, Name ?? repoFolder.Folder);
|
||||||
|
|
||||||
|
GitManager.ClearDebugWriter();
|
||||||
|
|
||||||
|
base.BeginProcessing();
|
||||||
}
|
}
|
||||||
else
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
// Not sure how we'd hit this path, but in case we do, show some sort of error.
|
WriteError(new ErrorRecord(ex, ex.Source, ErrorCategory.FromStdErr, null));
|
||||||
// TODO: I should probably have IsGitRepo throw instead so I can get the location it tried in the stack track
|
|
||||||
WriteError(new ErrorRecord(
|
|
||||||
new Exception("Unable to register repo - failed to parse git repo location"),
|
|
||||||
"git-parse-failed",
|
|
||||||
ErrorCategory.InvalidData,
|
|
||||||
null
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GitManager.ClearDebugWriter();
|
|
||||||
|
|
||||||
base.BeginProcessing();
|
|
||||||
}
|
|
||||||
|
|
||||||
private ParsedGitFolderDetails? IsGitRepo(string path)
|
|
||||||
{
|
|
||||||
WriteDebug("Checking if current directory is a git repository...");
|
|
||||||
|
|
||||||
var ps = new ProcessStartInfo("git",
|
|
||||||
["-C", path, "rev-parse", "--show-toplevel"])
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
var directory = gitProcess.StandardOutput.ReadToEnd();
|
|
||||||
// Gotta trim what we get as it might already have a newline character at the end
|
|
||||||
var dirInfo = new DirectoryInfo(directory.Trim());
|
|
||||||
|
|
||||||
WriteDebug("...location is a git repo (duh).");
|
|
||||||
|
|
||||||
var repoFolderInfo = new ParsedGitFolderDetails
|
|
||||||
{
|
|
||||||
Directory = dirInfo.FullName,
|
|
||||||
Folder = dirInfo.Name,
|
|
||||||
};
|
|
||||||
|
|
||||||
return repoFolderInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!gitProcess.StandardError.EndOfStream)
|
|
||||||
{
|
|
||||||
var errorAsException = new Exception(gitProcess.StandardError.ReadToEnd());
|
|
||||||
WriteError(new ErrorRecord(errorAsException, "git-not-found", ErrorCategory.FromStdErr, null));
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The directory details of the directory returned from git rev-parse --show-toplevel
|
|
||||||
/// </summary>
|
|
||||||
private 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!;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in a new issue