diff --git a/src/GitHubActionsVS.csproj b/src/GitHubActionsVS.csproj
index c734762..839ac6f 100644
--- a/src/GitHubActionsVS.csproj
+++ b/src/GitHubActionsVS.csproj
@@ -54,6 +54,7 @@
+
diff --git a/src/Helpers/GitUri.cs b/src/Helpers/GitUri.cs
new file mode 100644
index 0000000..db90736
--- /dev/null
+++ b/src/Helpers/GitUri.cs
@@ -0,0 +1,106 @@
+using System.Text.RegularExpressions;
+
+namespace GitHubActionsVS.Helpers;
+
+internal class GitUri
+{
+ public string OriginalUri { get; }
+ public string Scheme { get; }
+ public string Host { get; }
+ public int? Port { get; }
+ public string Path { get; }
+
+ private GitUri(string originalUri, string scheme, string host, int? port, string path)
+ {
+ OriginalUri = originalUri;
+ Scheme = scheme;
+ Host = host;
+ Port = port;
+ Path = path;
+ }
+
+ public static GitUri Parse(string originalUri)
+ {
+ GitUri gitUri = null;
+ originalUri = originalUri?.Trim();
+ if (!string.IsNullOrEmpty(originalUri))
+ {
+ Uri uri;
+ if (Uri.TryCreate(originalUri, UriKind.Absolute, out uri) && !string.IsNullOrEmpty(uri.Host))
+ {
+ gitUri = new GitUri(originalUri, uri.Scheme, uri.Host, GetUriPort(uri), uri.AbsolutePath);
+ }
+ else if (!originalUri.Contains("://") && Uri.TryCreate("https://" + originalUri, UriKind.Absolute, out uri) && !string.IsNullOrEmpty(uri.Host))
+ {
+ gitUri = new GitUri(originalUri, null, uri.Host, GetUriPort(uri), uri.AbsolutePath);
+ }
+ else
+ {
+ // ssh style git URI: git@github.com:owner/repo.git
+ Match match = new Regex("^(?:(?:.+)@)?(?'host'[^\\:\\/]+)\\:(?:(?'port'\\d+/)?)?(?'path'.+)$").Match(originalUri);
+ if (match.Success)
+ {
+ string host = match.Groups["host"].Value;
+ int? port = null;
+ string portValue = match.Groups["port"].Value;
+ if (!string.IsNullOrEmpty(portValue))
+ {
+ if (int.TryParse(portValue.TrimEnd(['/']), out int parsedPort))
+ {
+ port = new int?(parsedPort);
+ }
+ }
+ string path = "/" + match.Groups["path"].Value;
+ gitUri = new GitUri(originalUri, null, host, port, path);
+ }
+ }
+ }
+ if (gitUri == null)
+ {
+ throw new UriFormatException("The provided URI is not a valid HTTP or SSH URI.");
+ }
+ return gitUri;
+ }
+
+ private static int? GetUriPort(Uri uri)
+ {
+ if (uri.Port != -1 && !uri.IsDefaultPort)
+ {
+ return uri.Port;
+ }
+ return null;
+ }
+
+ public string GetRepositoryName()
+ {
+ if (string.IsNullOrEmpty(Path))
+ {
+ return null;
+ }
+ string[] segments = Path.Split('/');
+ if (segments.Length > 0)
+ {
+ string lastSegment = segments[segments.Length - 1];
+ if (lastSegment.EndsWith(".git"))
+ {
+ return lastSegment.Substring(0, lastSegment.Length - 4);
+ }
+ return lastSegment;
+ }
+ return null;
+ }
+
+ public string GetRepositoryOwner()
+ {
+ if (string.IsNullOrEmpty(Path))
+ {
+ return null;
+ }
+ string[] segments = Path.Split('/');
+ if (segments.Length > 1)
+ {
+ return segments[segments.Length - 2];
+ }
+ return null;
+ }
+}
diff --git a/src/Helpers/RepoInfo.cs b/src/Helpers/RepoInfo.cs
index 978146a..17dc89a 100644
--- a/src/Helpers/RepoInfo.cs
+++ b/src/Helpers/RepoInfo.cs
@@ -10,39 +10,36 @@ internal class RepoInfo
public string RepoUrl { get; set; }
public string CurrentBranch { get; set; }
-
- internal void FindGitFolder(string path, out string foundPath)
+ internal bool TryFindGitFolder(string path, out string foundPath)
{
foundPath = null;
- // Check if the current directory contains a .git folder
- if (Directory.Exists(Path.Combine(path, ".git")))
+ string currentPath = path;
+
+ while (!string.IsNullOrEmpty(currentPath))
{
- foundPath = path;
- var repo = new LibGit2Sharp.Repository(foundPath);
- var remote = repo.Network.Remotes.FirstOrDefault();
- if (remote is not null)
+ // Check if the current directory contains a .git folder
+ if (Directory.Exists(Path.Combine(currentPath, ".git")))
{
- var url = remote.Url;
- if (url.Contains("github.com"))
+ foundPath = currentPath;
+ var repo = new LibGit2Sharp.Repository(foundPath);
+ var remote = repo.Network.Remotes.FirstOrDefault();
+ if (remote is not null)
{
- IsGitHub = true;
- var parts = url.Split('/');
- RepoOwner = parts[parts.Length - 2];
- RepoName = parts[parts.Length - 1].Replace(".git", "");
- RepoUrl = url.Replace(".git", "");
+ var remoteUri = GitUri.Parse(remote.Url);
+ RepoOwner = remoteUri.GetRepositoryOwner();
+ RepoName = remoteUri.GetRepositoryName();
+ RepoUrl = $"https://{remoteUri.Host}{(remoteUri.Port is not null ? $":{remoteUri.Port}" : "")}/{RepoOwner}/{RepoName}";
CurrentBranch = repo.Head.FriendlyName;
+ IsGitHub = remoteUri.Host == "github.com";
}
+
+ return true;
}
- return;
- }
- else
- {
- string parentPath = Directory.GetParent(path)?.FullName;
- if (!string.IsNullOrEmpty(parentPath))
- {
- FindGitFolder(parentPath, out foundPath); // Recursively search the parent directory
- }
+
+ // Move to parent directory
+ currentPath = Directory.GetParent(currentPath)?.FullName;
}
- return;
+
+ return false;
}
}
diff --git a/src/ToolWindows/GHActionsToolWindow.xaml.cs b/src/ToolWindows/GHActionsToolWindow.xaml.cs
index 9a58404..94f6a80 100644
--- a/src/ToolWindows/GHActionsToolWindow.xaml.cs
+++ b/src/ToolWindows/GHActionsToolWindow.xaml.cs
@@ -112,9 +112,9 @@ public async Task GetRepoInfoAsync()
}
var projectPath = solution?.FullPath;
- _repoInfo.FindGitFolder(projectPath, out string gitPath);
+ var found = _repoInfo.TryFindGitFolder(projectPath, out string gitPath);
- if (string.IsNullOrWhiteSpace(gitPath))
+ if (!found)
{
await _pane.WriteLineAsync($"[{DateTime.UtcNow.ToString("o")}] No git repo found");
Debug.WriteLine("No git repo found");