Mike Phares f2e714730f GitRemoteRemove
Handle directoryInfo.LinkTarget better
2024-07-11 18:33:59 -07:00

120 lines
5.2 KiB
C#

using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Text;
namespace File_Folder_Helper.Helpers;
internal static class HelperGit
{
private record ProcessResult(string Errors,
int ExitCode,
string Output);
private static async Task<ProcessResult> RunProcessAsync(string application, string arguments, string workingDirectory, CancellationToken cancellationToken)
{
using Process process = new();
StringBuilder outputBuilder = new();
StringBuilder errorsBuilder = new();
process.StartInfo = new ProcessStartInfo
{
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardOutput = true,
FileName = application,
Arguments = arguments,
WorkingDirectory = workingDirectory,
};
process.OutputDataReceived += (_, args) => outputBuilder.AppendLine(args.Data);
process.ErrorDataReceived += (_, args) => errorsBuilder.AppendLine(args.Data);
_ = process.Start();
process.BeginErrorReadLine();
process.BeginOutputReadLine();
await process.WaitForExitAsync(cancellationToken);
return new(errorsBuilder.ToString().Trim(), process.ExitCode, outputBuilder.ToString().Trim());
}
private static async Task<string> RunAsync(string arguments, string workingDirectory, CancellationToken cancellationToken)
{
ProcessResult result = await RunProcessAsync("git", arguments, workingDirectory, cancellationToken);
if (result.ExitCode != 0)
throw new Exception($"{result.ExitCode} {result.Errors}");
return result.Output;
}
private static List<string> GetOthersModifiedAndDeletedExcludingStandardFilesAsList(string repositoryDirectory, bool usePathCombine, CancellationToken cancellationToken)
{
List<string> results = [];
Task<string> task = RunAsync("ls-files --others --modified --deleted --exclude-standard", repositoryDirectory, cancellationToken);
task.Wait(cancellationToken);
string[] files = task.Result.Split("\r\n");
foreach (string file in files)
{
if (!usePathCombine)
results.Add(file);
else
results.Add(Path.GetFullPath(Path.Combine(repositoryDirectory, file)));
}
return results;
}
internal static ReadOnlyCollection<string> GetOthersModifiedAndDeletedExcludingStandardFiles(string repositoryDirectory, bool usePathCombine, CancellationToken cancellationToken)
{
List<string> results = [];
List<string> relativePathFiles;
DirectoryInfo directoryInfo;
bool usePathCombineInner = false;
string checkDirectory = Path.Combine(repositoryDirectory, ".git");
if (Directory.Exists(checkDirectory))
results.AddRange(GetOthersModifiedAndDeletedExcludingStandardFilesAsList(repositoryDirectory, usePathCombine, cancellationToken));
string[] subdirectories = Directory.GetDirectories(repositoryDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string subdirectory in subdirectories)
{
directoryInfo = new(subdirectory);
if (directoryInfo.LinkTarget is null)
continue;
checkDirectory = Path.Combine(directoryInfo.LinkTarget, ".git");
if (!Directory.Exists(checkDirectory))
continue;
relativePathFiles = GetOthersModifiedAndDeletedExcludingStandardFilesAsList(directoryInfo.LinkTarget, usePathCombineInner, cancellationToken);
foreach (string relativePathFile in relativePathFiles)
results.Add(Path.GetFullPath(Path.Combine(subdirectory, relativePathFile)));
}
return new(results);
}
internal static ReadOnlyCollection<string> RemoteRemove(string repositoryDirectory, string name, CancellationToken cancellationToken)
{
List<string> results = [];
Task<string> task = RunAsync($"remote rm {name}", repositoryDirectory, cancellationToken);
task.Wait(cancellationToken);
string[] lines = task.Result.Split("\r\n");
foreach (string line in lines)
results.Add(line);
return new(results);
}
internal static ReadOnlyCollection<string> RemoteAdd(string repositoryDirectory, string name, string url, CancellationToken cancellationToken)
{
List<string> results = [];
Task<string> task = RunAsync($"remote add {name} {url}", repositoryDirectory, cancellationToken);
task.Wait(cancellationToken);
string[] lines = task.Result.Split("\r\n");
foreach (string line in lines)
results.Add(line);
return new(results);
}
internal static ReadOnlyCollection<string> PushBranch(string repositoryDirectory, string remote, string name, CancellationToken cancellationToken)
{
List<string> results = [];
Task<string> task = RunAsync($"push {remote} {name}", repositoryDirectory, cancellationToken);
task.Wait(cancellationToken);
string[] lines = task.Result.Split("\r\n");
foreach (string line in lines)
results.Add(line);
return new(results);
}
}