Forge
csharpdeeb25a2
1namespace CascadeIDE.Features.Intercom.Transport;
2
3/// <summary>Нормализация git remote URL (ADR 0144 §2.3.1).</summary>
4public static class IntercomGitRepoUrlNormalizer
5{
6 public static string? TryNormalize(string? raw)
7 {
8 if (string.IsNullOrWhiteSpace(raw))
9 return null;
10
11 var url = raw.Trim();
12 if (url.EndsWith(".git", StringComparison.OrdinalIgnoreCase))
13 url = url[..^4];
14
15 if (url.StartsWith("git@", StringComparison.Ordinal))
16 {
17 var at = url.IndexOf('@');
18 var colon = url.IndexOf(':', at + 1);
19 if (colon < 0)
20 return null;
21 var sshHost = url[(at + 1)..colon].ToLowerInvariant();
22 var sshPath = url[(colon + 1)..].Trim('/');
23 return $"{sshHost}/{sshPath.ToLowerInvariant()}";
24 }
25
26 if (!Uri.TryCreate(url, UriKind.Absolute, out var uri))
27 {
28 var slash = url.IndexOf('/');
29 if (slash <= 0)
30 return null;
31 var bareHost = url[..slash].ToLowerInvariant();
32 var barePath = url[(slash + 1)..].Trim('/');
33 if (string.IsNullOrWhiteSpace(barePath))
34 return null;
35 return $"{bareHost}/{barePath.ToLowerInvariant()}";
36 }
37
38 if (!string.Equals(uri.Scheme, "https", StringComparison.OrdinalIgnoreCase)
39 && !string.Equals(uri.Scheme, "http", StringComparison.OrdinalIgnoreCase))
40 return null;
41
42 var host = uri.Host.ToLowerInvariant();
43 var path = uri.AbsolutePath.Trim('/');
44 if (string.IsNullOrWhiteSpace(path))
45 return null;
46
47 return $"{host}/{path.ToLowerInvariant()}";
48 }
49}
50
View only · write via MCP/CIDE