Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions openhands-sdk/openhands/sdk/git/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,13 +309,19 @@ def is_git_url(source: str) -> bool:
True
>>> is_git_url("git@github.com:owner/repo.git")
True
>>> is_git_url("ssh://git@github.com/owner/repo.git")
True
>>> is_git_url("/local/path")
False
"""
# HTTPS/HTTP URLs to git repositories
if source.startswith(("https://", "http://")):
return True

# SSH URL with explicit scheme: ssh://git@host[:port]/path
if source.startswith("ssh://"):
return True

# SSH format: git@host:path or user@host:path
if re.match(r"^[\w.-]+@[\w.-]+:", source):
return True
Expand Down
13 changes: 13 additions & 0 deletions tests/sdk/extensions/test_fetch.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,19 @@ def test_parse_ssh_with_custom_user():
assert url == ssh_url


def test_parse_ssh_scheme_url():
"""`ssh://` scheme URLs (incl. an explicit port) are recognized as git URLs.

Regression test: previously `is_git_url()` did not recognize the `ssh://`
scheme, so these dropped through to "Unable to parse extension source"
instead of being treated as a git source.
"""
ssh_url = "ssh://git@bitbucket.example.com:7999/team/repo.git"
source_type, url = parse_extension_source(ssh_url)
assert source_type == SourceType.GIT
assert url == ssh_url


def test_parse_relative_path_with_slash():
source_type, url = parse_extension_source("extensions/my-ext")
assert source_type == SourceType.LOCAL
Expand Down
Loading