|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Diagnostics;
using Microsoft.Extensions.Logging;
namespace Aspire.Cli.Git;
/// <summary>
/// Provides Git repository operations.
/// </summary>
/// <param name="executionContext">The CLI execution context providing the working directory.</param>
/// <param name="logger">The logger for diagnostic output.</param>
internal sealed class GitRepository(CliExecutionContext executionContext, ILogger<GitRepository> logger) : IGitRepository
{
/// <inheritdoc />
public async Task<DirectoryInfo?> GetRootAsync(CancellationToken cancellationToken)
{
logger.LogDebug("Searching for Git repository root from working directory: {WorkingDirectory}", executionContext.WorkingDirectory.FullName);
try
{
var startInfo = new ProcessStartInfo("git", "rev-parse --show-toplevel")
{
WorkingDirectory = executionContext.WorkingDirectory.FullName,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
};
using var process = new Process { StartInfo = startInfo };
process.Start();
var outputTask = process.StandardOutput.ReadToEndAsync(cancellationToken);
var errorTask = process.StandardError.ReadToEndAsync(cancellationToken);
await process.WaitForExitAsync(cancellationToken).ConfigureAwait(false);
if (process.ExitCode != 0)
{
var errorOutput = await errorTask.ConfigureAwait(false);
logger.LogDebug("Git command returned non-zero exit code {ExitCode}: {Error}", process.ExitCode, errorOutput.Trim());
return null;
}
var output = await outputTask.ConfigureAwait(false);
var rootPath = output.Trim();
if (string.IsNullOrEmpty(rootPath))
{
logger.LogDebug("Git command returned empty output");
return null;
}
var directoryInfo = new DirectoryInfo(rootPath);
if (directoryInfo.Exists)
{
logger.LogDebug("Found Git repository root: {GitRoot}", directoryInfo.FullName);
return directoryInfo;
}
logger.LogDebug("Git repository root path does not exist: {GitRoot}", rootPath);
return null;
}
catch (Exception ex) when (ex is InvalidOperationException or System.ComponentModel.Win32Exception)
{
logger.LogDebug(ex, "Git is not installed or not found in PATH");
return null;
}
}
}
|