mirror of
https://github.com/go-gitea/gitea
synced 2025-01-10 09:44:43 +00:00
34dfc25b83
close #33086 * Add a special value for "SSH_USER" setting: `(DOER_USERNAME)` * Improve parseRepositoryURL and add tests (now it doesn't have hard dependency on some setting values) Many changes are just adding "ctx" and "doer" argument to functions. By the way, improve app.example.ini, remove all `%(key)s` syntax, it only makes messy and no user really cares about it. Document: https://gitea.com/gitea/docs/pulls/138
93 lines
1.9 KiB
Go
93 lines
1.9 KiB
Go
// Copyright 2022 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package url
|
|
|
|
import (
|
|
"fmt"
|
|
stdurl "net/url"
|
|
"strings"
|
|
)
|
|
|
|
// ErrWrongURLFormat represents an error with wrong url format
|
|
type ErrWrongURLFormat struct {
|
|
URL string
|
|
}
|
|
|
|
func (err ErrWrongURLFormat) Error() string {
|
|
return fmt.Sprintf("git URL %s format is wrong", err.URL)
|
|
}
|
|
|
|
// GitURL represents a git URL
|
|
type GitURL struct {
|
|
*stdurl.URL
|
|
extraMark int // 0: standard URL with scheme, 1: scp short syntax (no scheme), 2: file path with no prefix
|
|
}
|
|
|
|
// String returns the URL's string
|
|
func (u *GitURL) String() string {
|
|
switch u.extraMark {
|
|
case 0:
|
|
return u.URL.String()
|
|
case 1:
|
|
return fmt.Sprintf("%s@%s:%s", u.User.Username(), u.Host, u.Path)
|
|
case 2:
|
|
return u.Path
|
|
default:
|
|
return ""
|
|
}
|
|
}
|
|
|
|
// ParseGitURL parse all kinds of git URL:
|
|
// * Full URL: http://git@host/path, http://git@host:port/path
|
|
// * SCP short syntax: git@host:/path
|
|
// * File path: /dir/repo/path
|
|
func ParseGitURL(remote string) (*GitURL, error) {
|
|
if strings.Contains(remote, "://") {
|
|
u, err := stdurl.Parse(remote)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &GitURL{URL: u}, nil
|
|
} else if strings.Contains(remote, "@") && strings.Contains(remote, ":") {
|
|
url := stdurl.URL{
|
|
Scheme: "ssh",
|
|
}
|
|
squareBrackets := false
|
|
lastIndex := -1
|
|
FOR:
|
|
for i := 0; i < len(remote); i++ {
|
|
switch remote[i] {
|
|
case '@':
|
|
url.User = stdurl.User(remote[:i])
|
|
lastIndex = i + 1
|
|
case ':':
|
|
if !squareBrackets {
|
|
url.Host = strings.ReplaceAll(remote[lastIndex:i], "%25", "%")
|
|
if len(remote) <= i+1 {
|
|
return nil, ErrWrongURLFormat{URL: remote}
|
|
}
|
|
url.Path = remote[i+1:]
|
|
break FOR
|
|
}
|
|
case '[':
|
|
squareBrackets = true
|
|
case ']':
|
|
squareBrackets = false
|
|
}
|
|
}
|
|
return &GitURL{
|
|
URL: &url,
|
|
extraMark: 1,
|
|
}, nil
|
|
}
|
|
|
|
return &GitURL{
|
|
URL: &stdurl.URL{
|
|
Scheme: "file",
|
|
Path: remote,
|
|
},
|
|
extraMark: 2,
|
|
}, nil
|
|
}
|