Skip to content

Commit 5948df3

Browse files
unhappychoiceclaude
andcommitted
fix: support SSH URLs with port numbers in GitRepositoryRefParser
- Add support for ssh:// URL format (ssh://git@host:port/owner/repo) - Add support for traditional SSH format with port (git@host:port:owner/repo) - Parse port number correctly by checking if it's numeric - Use next_back() instead of last() for better performance per clippy 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 86de445 commit 5948df3

File tree

1 file changed

+51
-3
lines changed

1 file changed

+51
-3
lines changed

src/infrastructure/git/git_repository_ref_parser.rs

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,67 @@ impl GitRepositoryRefParser {
1717
}
1818

1919
fn parse_ssh_format(repo_spec: &str) -> Result<GitRepositoryRef> {
20-
let (host_part, repo_part) = repo_spec.split_once(':').ok_or_else(|| {
20+
// Handle ssh:// URL format
21+
if let Some(url_part) = repo_spec.strip_prefix("ssh://") {
22+
// Parse ssh://[user@]host[:port]/owner/repo format
23+
let (host_with_user, path) = url_part.split_once('/').ok_or_else(|| {
24+
GitTypeError::InvalidRepositoryFormat("Invalid SSH URL format".to_string())
25+
})?;
26+
27+
// Extract host (remove user@ prefix and port suffix if present)
28+
let host = host_with_user
29+
.split('@')
30+
.next_back()
31+
.unwrap_or(host_with_user);
32+
33+
// Parse owner/repo from path
34+
let (owner, name) = path
35+
.strip_suffix(".git")
36+
.unwrap_or(path)
37+
.split_once('/')
38+
.ok_or_else(|| {
39+
GitTypeError::InvalidRepositoryFormat(
40+
"Invalid repository path format".to_string(),
41+
)
42+
})?;
43+
44+
return Ok(GitRepositoryRef {
45+
origin: host.to_string(),
46+
owner: owner.to_string(),
47+
name: name.to_string(),
48+
});
49+
}
50+
51+
// Handle traditional git@host:path format
52+
let (host_part, path_part) = repo_spec.split_once(':').ok_or_else(|| {
2153
GitTypeError::InvalidRepositoryFormat("Invalid SSH repository format".to_string())
2254
})?;
2355

56+
// Extract origin (host) from git@host part
2457
let origin = host_part
2558
.split('@')
2659
.nth(1)
2760
.unwrap_or("github.com")
2861
.to_string();
2962

30-
let (owner, name) = repo_part
63+
// Handle port number in path: host:port:owner/repo or host:owner/repo
64+
let repo_path = if let Some((maybe_port, rest)) = path_part.split_once(':') {
65+
// Check if the first part is a port number
66+
if maybe_port.parse::<u16>().is_ok() {
67+
// This is a port number, use the rest as the path
68+
rest
69+
} else {
70+
// Not a port number, use the entire path_part
71+
path_part
72+
}
73+
} else {
74+
path_part
75+
};
76+
77+
// Parse owner/repo from the path
78+
let (owner, name) = repo_path
3179
.strip_suffix(".git")
32-
.unwrap_or(repo_part)
80+
.unwrap_or(repo_path)
3381
.split_once('/')
3482
.ok_or_else(|| {
3583
GitTypeError::InvalidRepositoryFormat("Invalid repository path format".to_string())

0 commit comments

Comments
 (0)