Update constructor calls (6-arg), seed AppSettings with sibling strategy, git-init working dirs via GitRepoFixture.InitRepoWithInitialCommit, and replace McpConfigPath assertions with worktree-path / .mcp.json checks. Also fixes PlanningHubTests which had the same 3-arg constructor. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
106 lines
3.2 KiB
C#
106 lines
3.2 KiB
C#
using System.Diagnostics;
|
|
|
|
namespace ClaudeDo.Worker.Tests.Infrastructure;
|
|
|
|
public sealed class GitRepoFixture : IDisposable
|
|
{
|
|
public string RepoDir { get; }
|
|
public string BaseCommit { get; }
|
|
|
|
public GitRepoFixture()
|
|
{
|
|
RepoDir = Path.Combine(Path.GetTempPath(), $"claudedo_gittest_{Guid.NewGuid():N}");
|
|
Directory.CreateDirectory(RepoDir);
|
|
|
|
RunGit(RepoDir, "init");
|
|
RunGit(RepoDir, "config", "user.name", "test");
|
|
RunGit(RepoDir, "config", "user.email", "test@example.com");
|
|
|
|
File.WriteAllText(Path.Combine(RepoDir, "README.md"), "# test repo");
|
|
RunGit(RepoDir, "add", "-A");
|
|
RunGit(RepoDir, "commit", "-m", "initial commit");
|
|
|
|
BaseCommit = RunGit(RepoDir, "rev-parse", "HEAD").Trim();
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
try
|
|
{
|
|
// Force-remove read-only .git objects on Windows.
|
|
ForceDeleteDirectory(RepoDir);
|
|
}
|
|
catch { /* best effort */ }
|
|
}
|
|
|
|
public static bool IsGitAvailable()
|
|
{
|
|
try
|
|
{
|
|
var psi = new ProcessStartInfo("git", "--version")
|
|
{
|
|
RedirectStandardOutput = true,
|
|
RedirectStandardError = true,
|
|
UseShellExecute = false,
|
|
CreateNoWindow = true,
|
|
};
|
|
using var p = Process.Start(psi)!;
|
|
p.WaitForExit(5000);
|
|
return p.ExitCode == 0;
|
|
}
|
|
catch
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
internal static string RunGit(string workDir, params string[] args)
|
|
{
|
|
var psi = new ProcessStartInfo("git")
|
|
{
|
|
RedirectStandardOutput = true,
|
|
RedirectStandardError = true,
|
|
UseShellExecute = false,
|
|
CreateNoWindow = true,
|
|
};
|
|
psi.ArgumentList.Add("-C");
|
|
psi.ArgumentList.Add(workDir);
|
|
foreach (var a in args) psi.ArgumentList.Add(a);
|
|
|
|
using var proc = Process.Start(psi)!;
|
|
var stdout = proc.StandardOutput.ReadToEnd();
|
|
var stderr = proc.StandardError.ReadToEnd();
|
|
proc.WaitForExit();
|
|
|
|
if (proc.ExitCode != 0)
|
|
throw new InvalidOperationException($"git {string.Join(' ', args)} failed: {stderr}");
|
|
|
|
return stdout;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new git repo at <paramref name="dir"/> with a seed commit.
|
|
/// Used by planning tests that need a real git repo as list working directory.
|
|
/// </summary>
|
|
public static void InitRepoWithInitialCommit(string dir)
|
|
{
|
|
Directory.CreateDirectory(dir);
|
|
RunGit(dir, "init", "-b", "main");
|
|
RunGit(dir, "config", "user.email", "test@claudedo.local");
|
|
RunGit(dir, "config", "user.name", "test");
|
|
File.WriteAllText(Path.Combine(dir, "README.md"), "seed\n");
|
|
RunGit(dir, "add", "-A");
|
|
RunGit(dir, "commit", "-m", "chore: seed");
|
|
}
|
|
|
|
private static void ForceDeleteDirectory(string path)
|
|
{
|
|
if (!Directory.Exists(path)) return;
|
|
foreach (var file in Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories))
|
|
{
|
|
File.SetAttributes(file, FileAttributes.Normal);
|
|
}
|
|
Directory.Delete(path, true);
|
|
}
|
|
}
|