Forge
csharpdeeb25a2
1namespace CascadeIDE.Features.Intercom.Transport;
2
3/// <summary>Чтение <c>origin</c> remote из git workspace (ADR 0144 §2.3.1).</summary>
4public static class IntercomWorkspaceGitRemoteResolver
5{
6 public static string? TryGetOriginRemoteUrl(string? workspaceRoot)
7 {
8 var gitRoot = FindGitRoot(workspaceRoot);
9 if (gitRoot is null)
10 return null;
11
12 var configPath = Path.Combine(gitRoot, ".git", "config");
13 if (!File.Exists(configPath))
14 return TryGitCli(gitRoot);
15
16 try
17 {
18 var lines = File.ReadAllLines(configPath);
19 var inOrigin = false;
20 foreach (var line in lines)
21 {
22 var trimmed = line.Trim();
23 if (trimmed.StartsWith('['))
24 {
25 inOrigin = trimmed.Equals("[remote \"origin\"]", StringComparison.OrdinalIgnoreCase);
26 continue;
27 }
28
29 if (!inOrigin)
30 continue;
31
32 if (trimmed.StartsWith("url =", StringComparison.OrdinalIgnoreCase))
33 return trimmed["url =".Length..].Trim();
34 }
35 }
36 catch
37 {
38 return TryGitCli(gitRoot);
39 }
40
41 return TryGitCli(gitRoot);
42 }
43
44 public static string? TryGetNormalizedOrigin(string? workspaceRoot)
45 {
46 var raw = TryGetOriginRemoteUrl(workspaceRoot);
47 return IntercomGitRepoUrlNormalizer.TryNormalize(raw);
48 }
49
50 private static string? FindGitRoot(string? workspaceRoot)
51 {
52 if (string.IsNullOrWhiteSpace(workspaceRoot))
53 return null;
54
55 var dir = new DirectoryInfo(Path.GetFullPath(workspaceRoot));
56 while (dir is not null)
57 {
58 var git = Path.Combine(dir.FullName, ".git");
59 if (Directory.Exists(git) || File.Exists(git))
60 return dir.FullName;
61 dir = dir.Parent;
62 }
63
64 return null;
65 }
66
67 private static string? TryGitCli(string gitRoot)
68 {
69 try
70 {
71 var psi = new System.Diagnostics.ProcessStartInfo
72 {
73 FileName = "git",
74 Arguments = "-C \"" + gitRoot + "\" remote get-url origin",
75 RedirectStandardOutput = true,
76 RedirectStandardError = true,
77 UseShellExecute = false,
78 CreateNoWindow = true,
79 };
80 using var proc = System.Diagnostics.Process.Start(psi);
81 if (proc is null)
82 return null;
83 var output = proc.StandardOutput.ReadToEnd().Trim();
84 proc.WaitForExit(3000);
85 return proc.ExitCode == 0 && !string.IsNullOrWhiteSpace(output) ? output : null;
86 }
87 catch
88 {
89 return null;
90 }
91 }
92}
93
View only · write via MCP/CIDE