diff --git a/git-open b/git-open index 6320f26..fc6a1c5 100755 --- a/git-open +++ b/git-open @@ -13,7 +13,9 @@ if ! git rev-parse --is-inside-work-tree &>/dev/null; then exit 1 fi +# Defaults is_issue=0 +protocol="https" # If the first argument is 'issue', we want to load the issue page if [[ "$1" == 'issue' ]]; then @@ -34,18 +36,35 @@ if [[ -z "$giturl" ]]; then exit 1 fi -# Initial case examples: 'git@example.com:user/project', 'https://example.com:8080/scm/user/project.git/' +# From git-fetch(5), native protocols: +# ssh://[user@]host.xz[:port]/path/to/repo.git/ +# git://host.xz[:port]/path/to/repo.git/ +# http[s]://host.xz[:port]/path/to/repo.git/ +# ftp[s]://host.xz[:port]/path/to/repo.git/ +# [user@]host.xz:path/to/repo.git/ - scp-like but is an alternative to ssh. + # Trim "/" and ".git" from the end of the url giturl=${giturl%/} giturl=${giturl%.git} # Trim before last '@' and protocol (*://) from beginning uri=${giturl##*@} uri=${uri##*://} -# Trims before first ':' or '/' to get path -urlpath=${uri#*[/:]} +# If there isn't a protocol, we can assume it's using the scp syntax which uses ':' to seperate the path. +[[ $giturl =~ :// ]] && pathsep='/' || pathsep=':' -# Trims after first ':' or '/' to remove path -server=${uri%%[/:]*} +# Seperate the domain and the urlpath on the first {pathsep}. This also removes the gitport from the domain. +domain=${uri%%[:$pathsep]*} urlpath=${uri#*$pathsep} + +# Allow config options to replace the server or the protocol +openurl="$protocol://$domain" + +function getConfig() { + config=$(git config --get-urlmatch "open.$1" "$openurl") + echo "${config:-${!1}}" +} + +domain=$(getConfig "domain") +protocol=$(getConfig "protocol") # Get current branch branch=${2:-$(git symbolic-ref -q --short HEAD)} @@ -63,7 +82,7 @@ else providerBranchRef="tree/$branch" fi -if [[ "$server" == 'bitbucket.org' ]]; then +if [[ "$domain" == 'bitbucket.org' ]]; then # Bitbucket, see https://github.com/paulirish/git-open/issues/80 for why ?at is needed. providerBranchRef="src?at=$branch" elif [[ ${pathargs[0]} == 'scm' ]]; then @@ -74,8 +93,7 @@ elif [[ ${pathargs[0]} == 'scm' ]]; then providerBranchRef="browse?at=$branch" fi -# @TODO: support non-https? -openurl="https://$server/$urlpath" +openurl="$protocol://$domain/$urlpath" # simplify URL for master if [[ $branch != "master" ]]; then diff --git a/test/git-open.bats b/test/git-open.bats old mode 100644 new mode 100755 index 2bdae81..1192dae --- a/test/git-open.bats +++ b/test/git-open.bats @@ -177,18 +177,6 @@ setup() { ## GitLab ## -@test "gitlab: separate domains" { - skip - # skipping until test is fixed: see #87 - - # https://github.com/paulirish/git-open/pull/56 - git remote set-url origin "git@git.example.com:namespace/project.git" - git config "gitopen.gitlab.domain" "gitlab.example.com" - git config "gitopen.gitlab.ssh.domain" "git.example.com" - run ../git-open - assert_output "https://gitlab.example.com/namespace/project" -} - @test "gitlab: default ssh origin style" { # https://github.com/paulirish/git-open/pull/55 git remote set-url origin "git@gitlab.example.com:user/repo" @@ -206,32 +194,36 @@ setup() { refute_output --partial "//user" } -@test "gitlab: ssh://git@host:port origin" { - skip - # skipping until test is fixed: see #87 - - # https://github.com/paulirish/git-open/pull/76 - # this first set mostly matches the "gitlab: ssh://git@ origin" test - git remote set-url origin "ssh://git@repo.intranet/XXX/YYY.git" - git config "gitopen.gitlab.domain" "repo.intranet" +@test "gitlab: separate domains" { + # https://github.com/paulirish/git-open/pull/56 + git remote set-url origin "git@git.example.com:namespace/project.git" + git config --local --add "open.https://git.example.com.domain" "gitlab.example.com" run ../git-open - assert_output "https://repo.intranet/XXX/YYY" - refute_output --partial "ssh://" - refute_output --partial "//XXX" - - git remote set-url origin "ssh://git@repo.intranet:7000/XXX/YYY.git" - git config "gitopen.gitlab.domain" "repo.intranet" - git config "gitopen.gitlab.ssh.port" "7000" - run ../git-open - assert_output "https://repo.intranet/XXX/YYY" - refute_output --partial "ssh://" - refute_output --partial "//XXX" + assert_output "https://gitlab.example.com/namespace/project" } -# Tests not yet written: -# * gitopen.gitlab.port -# * gitopen.gitlab.protocol +@test "gitlab: special domain and path" { + git remote set-url origin "ssh://git@git.example.com:7000/XXX/YYY.git" + git config --local --add "open.https://git.example.com.domain" "repo.intranet/subpath" + git config --local --add "open.https://git.example.com.protocol" "http" + run ../git-open + assert_output "http://repo.intranet/subpath/XXX/YYY" + refute_output --partial "https://" +} + +@test "gitlab: different port" { + # https://github.com/paulirish/git-open/pull/76 + git remote set-url origin "ssh://git@git.example.com:7000/XXX/YYY.git" + run ../git-open + assert_output "https://git.example.com/XXX/YYY" + refute_output --partial ":7000" + + git remote set-url origin "https://git.example.com:7000/XXX/YYY.git" + run ../git-open + assert_output "https://git.example.com/XXX/YYY" + refute_output --partial ":7000" +} teardown() { cd ..