Skip to content

Commit

Permalink
Provide mechanism for configuring submodule aliases
Browse files Browse the repository at this point in the history
Sometimes Gitea users would like submodules when displayed on the website to have
a different alias than what is normally inferred by gitea.

This PR provides a mechanism to configure this.

Fix go-gitea#15178

Signed-off-by: Andrew Thornton <[email protected]>
  • Loading branch information
zeripath committed Mar 27, 2021
1 parent 6b836ac commit ecb943b
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 23 deletions.
7 changes: 7 additions & 0 deletions custom/conf/app.example.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1145,6 +1145,13 @@ CLONE = 300
PULL = 300
GC = 60

; Submodule aliase
; [git.submodule]
; MAP_NAME_1 = [email protected]
; MAP_VALUE_1 = https://example.com
; MAP_NAME_2 = [email protected]/go-gitea/gitea
; MAP_VALUE_2 = https://gitea.com/gitea/gitea

[mirror]
; Default interval as a duration between each check
DEFAULT_INTERVAL = 8h
Expand Down
7 changes: 7 additions & 0 deletions docs/content/doc/advanced/config-cheat-sheet.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -782,13 +782,20 @@ NB: You must have `DISABLE_ROUTER_LOG` set to `false` for this option to take ef
- `VERBOSE_PUSH_DELAY`: **5s**: Only print verbose information if push takes longer than this delay.

## Git - Timeout settings (`git.timeout`)

- `DEFAUlT`: **360**: Git operations default timeout seconds.
- `MIGRATE`: **600**: Migrate external repositories timeout seconds.
- `MIRROR`: **300**: Mirror external repositories timeout seconds.
- `CLONE`: **300**: Git clone from internal repositories timeout seconds.
- `PULL`: **300**: Git pull from internal repositories timeout seconds.
- `GC`: **60**: Git repository GC timeout seconds.

## Git - Submodule alias settings (`git.submodule`)

- List of `MAP_NAME_` and `MAP_VALUE_` pairs that map submodule urls or partial urls to web paths. For example:
- `MAP_NAME_1 = [email protected]` & `MAP_VALUE_1 = https://external` would convert any submodules referring to `[email protected]` to `https://external`
- `MAP_NAME_A = [email protected]:owner/repo` & `MAP_VALUE_A = https://external/externalowner/externalrepo`

## Metrics (`metrics`)

- `ENABLED`: **false**: Enables /metrics endpoint for prometheus.
Expand Down
2 changes: 2 additions & 0 deletions modules/git/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ var (

// will be checked on Init
goVersionLessThan115 = true

SubModuleMap = map[string]string{}
)

func log(format string, args ...interface{}) {
Expand Down
39 changes: 39 additions & 0 deletions modules/git/submodule.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,16 @@ func getRefURL(refURL, urlPrefix, repoFullName, sshDomain string) string {
return ""
}

if alias, ok := SubModuleMap[refURL]; ok {
return alias
}

refURI := strings.TrimSuffix(refURL, ".git")

if alias, ok := SubModuleMap[refURI]; ok {
return alias
}

prefixURL, _ := url.Parse(urlPrefix)
urlPrefixHostname, _, err := net.SplitHostPort(prefixURL.Host)
if err != nil {
Expand Down Expand Up @@ -76,6 +84,10 @@ func getRefURL(refURL, urlPrefix, repoFullName, sshDomain string) string {
pth = "/" + pth
}

if alias, ok := SubModuleMap[m[1]+refHostname]; ok {
return alias + pth
}

if urlPrefixHostname == refHostname || refHostname == sshDomain {
return urlPrefix + path.Clean(path.Join("/", pth))
}
Expand All @@ -95,6 +107,33 @@ func getRefURL(refURL, urlPrefix, repoFullName, sshDomain string) string {

supportedSchemes := []string{"http", "https", "git", "ssh", "git+ssh"}

if len(SubModuleMap) > 0 && ref.Scheme != "" {
if ref.Scheme == "ssh" {
if len(ref.User.Username()) > 0 {
if alias, ok := SubModuleMap[fmt.Sprintf("%v@%s:%s", ref.User, ref.Host, ref.Path[1:])]; ok {
return alias
}
if alias, ok := SubModuleMap[fmt.Sprintf("%v@%s", ref.User, ref.Host)]; ok {
return alias + ref.Path
}
} else if alias, ok := SubModuleMap[ref.Host+":"+ref.Path[1:]]; ok {
return alias
} else if alias, ok := SubModuleMap[ref.Host]; ok {
return alias + ref.Path
}
}
left := refURI
right := ""
for idx := strings.LastIndex(left, "/"); idx > len(ref.Scheme)+3; {
right = left[idx:] + right
left = left[:idx]
if alias, ok := SubModuleMap[left]; ok {
return alias + right
}
idx = strings.LastIndex(left, "/")
}
}

for _, scheme := range supportedSchemes {
if ref.Scheme == scheme {
if ref.Scheme == "http" || ref.Scheme == "https" {
Expand Down
69 changes: 46 additions & 23 deletions modules/git/submodule_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,32 +12,55 @@ import (

func TestGetRefURL(t *testing.T) {
var kases = []struct {
refURL string
prefixURL string
parentPath string
SSHDomain string
expect string
refURL string
prefixURL string
parentPath string
SSHDomain string
expect string
subModuleMap map[string]string
}{
{"git://github.com/user1/repo1", "/", "user1/repo2", "", "http://github.com/user1/repo1"},
{"https://localhost/user1/repo1.git", "/", "user1/repo2", "", "https://localhost/user1/repo1"},
{"http://localhost/user1/repo1.git", "/", "owner/reponame", "", "http://localhost/user1/repo1"},
{"[email protected]:user1/repo1.git", "/", "owner/reponame", "", "http://github.com/user1/repo1"},
{"ssh://[email protected]:2222/zefie/lge_g6_kernel_scripts.git", "/", "zefie/lge_g6_kernel", "", "http://git.zefie.net/zefie/lge_g6_kernel_scripts"},
{"[email protected]:2222/zefie/lge_g6_kernel_scripts.git", "/", "zefie/lge_g6_kernel", "", "http://git.zefie.net/2222/zefie/lge_g6_kernel_scripts"},
{"[email protected]:go-gitea/gitea", "https://try.gitea.io/", "go-gitea/sdk", "", "https://try.gitea.io/go-gitea/gitea"},
{"ssh://[email protected]:9999/go-gitea/gitea", "https://try.gitea.io/", "go-gitea/sdk", "", "https://try.gitea.io/go-gitea/gitea"},
{"git://[email protected]:9999/go-gitea/gitea", "https://try.gitea.io/", "go-gitea/sdk", "", "https://try.gitea.io/go-gitea/gitea"},
{"ssh://[email protected]:9999/go-gitea/gitea", "https://127.0.0.1:3000/", "go-gitea/sdk", "", "https://127.0.0.1:3000/go-gitea/gitea"},
{"https://gitea.com:3000/user1/repo1.git", "https://127.0.0.1:3000/", "user/repo2", "", "https://gitea.com:3000/user1/repo1"},
{"https://example.gitea.com/gitea/user1/repo1.git", "https://example.gitea.com/gitea/", "", "user/repo2", "https://example.gitea.com/gitea/user1/repo1"},
{"https://username:[email protected]/username/repository.git", "/", "username/repository2", "", "https://username:[email protected]/username/repository"},
{"somethingbad", "https://127.0.0.1:3000/go-gitea/gitea", "/", "", ""},
{"git@localhost:user/repo", "https://localhost/", "user2/repo1", "", "https://localhost/user/repo"},
{"../path/to/repo.git/", "https://localhost/", "user/repo2", "", "https://localhost/user/path/to/repo.git"},
{"ssh://[email protected]:2222/go-gitea/gitea", "https://try.gitea.io/", "go-gitea/sdk", "ssh.gitea.io", "https://try.gitea.io/go-gitea/gitea"},
{"git://github.com/user1/repo1", "/", "user1/repo2", "", "http://github.com/user1/repo1", map[string]string{}},
{"https://localhost/user1/repo1.git", "/", "user1/repo2", "", "https://localhost/user1/repo1", map[string]string{}},
{"http://localhost/user1/repo1.git", "/", "owner/reponame", "", "http://localhost/user1/repo1", map[string]string{}},
{"[email protected]:user1/repo1.git", "/", "owner/reponame", "", "http://github.com/user1/repo1", map[string]string{}},
{"ssh://[email protected]:2222/zefie/lge_g6_kernel_scripts.git", "/", "zefie/lge_g6_kernel", "", "http://git.zefie.net/zefie/lge_g6_kernel_scripts", map[string]string{}},
{"[email protected]:2222/zefie/lge_g6_kernel_scripts.git", "/", "zefie/lge_g6_kernel", "", "http://git.zefie.net/2222/zefie/lge_g6_kernel_scripts", map[string]string{}},
{"[email protected]:go-gitea/gitea", "https://try.gitea.io/", "go-gitea/sdk", "", "https://try.gitea.io/go-gitea/gitea", map[string]string{}},
{"ssh://[email protected]:9999/go-gitea/gitea", "https://try.gitea.io/", "go-gitea/sdk", "", "https://try.gitea.io/go-gitea/gitea", map[string]string{}},
{"git://[email protected]:9999/go-gitea/gitea", "https://try.gitea.io/", "go-gitea/sdk", "", "https://try.gitea.io/go-gitea/gitea", map[string]string{}},
{"ssh://[email protected]:9999/go-gitea/gitea", "https://127.0.0.1:3000/", "go-gitea/sdk", "", "https://127.0.0.1:3000/go-gitea/gitea", map[string]string{}},
{"https://gitea.com:3000/user1/repo1.git", "https://127.0.0.1:3000/", "user/repo2", "", "https://gitea.com:3000/user1/repo1", map[string]string{}},
{"https://example.gitea.com/gitea/user1/repo1.git", "https://example.gitea.com/gitea/", "", "user/repo2", "https://example.gitea.com/gitea/user1/repo1", map[string]string{}},
{"https://username:[email protected]/username/repository.git", "/", "username/repository2", "", "https://username:[email protected]/username/repository", map[string]string{}},
{"somethingbad", "https://127.0.0.1:3000/go-gitea/gitea", "/", "", "", map[string]string{}},
{"git@localhost:user/repo", "https://localhost/", "user2/repo1", "", "https://localhost/user/repo", map[string]string{}},
{"../path/to/repo.git/", "https://localhost/", "user/repo2", "", "https://localhost/user/path/to/repo.git", map[string]string{}},
{"ssh://[email protected]:2222/go-gitea/gitea", "https://try.gitea.io/", "go-gitea/sdk", "ssh.gitea.io", "https://try.gitea.io/go-gitea/gitea", map[string]string{}},
{"ssh://[email protected]:2222/go-gitea/gitea", "https://try.gitea.io/", "go-gitea/sdk", "try.gitea.io", "https://try.gitea.io/go-gitea/gitea", map[string]string{
"ssh://[email protected]:2222": "https://try.gitea.io",
}},
{"[email protected]:go-gitea/gitea", "https://try.gitea.io/", "go-gitea/sdk", "try.gitea.io", "https://try.gitea.io/go-gitea/gitea", map[string]string{
"[email protected]": "https://try.gitea.io",
"ssh://[email protected]:2222": "Wrong",
}},
{"ssh://[email protected]/go-gitea/gitea", "https://try.gitea.io/", "go-gitea/sdk", "try.gitea.io", "https://try.gitea.io/go-gitea/gitea", map[string]string{
"ssh://[email protected]": "https://try.gitea.io",
"ssh://[email protected]:2222": "Wrong",
}},
{"ssh://[email protected]/go-gitea/gitea", "https://try.gitea.io/", "go-gitea/sdk", "try.gitea.io", "https://try.gitea.io/go-gitea/gitea", map[string]string{
"[email protected]": "https://try.gitea.io",
}},
{"ssh://[email protected]/go-gitea/gitea", "https://try.gitea.io/", "go-gitea/sdk", "try.gitea.io", "https://try.gitea.io/go-gitea/gitea", map[string]string{
"[email protected]": "https://try.gitea.io",
}},
{"ssh://[email protected]/go-gitea/gitea", "https://try.gitea.io/", "go-gitea/sdk", "try.gitea.io", "https://try.gitea.io/go-gitea/gitea", map[string]string{
"[email protected]:go-gitea/gitea": "https://try.gitea.io/go-gitea/gitea",
}},
}

orig := SubModuleMap
for _, kase := range kases {
SubModuleMap = kase.subModuleMap
assert.EqualValues(t, kase.expect, getRefURL(kase.refURL, kase.prefixURL, kase.parentPath, kase.SSHDomain))
}
SubModuleMap = orig
}
19 changes: 19 additions & 0 deletions modules/setting/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package setting

import (
"strings"
"time"

"code.gitea.io/gitea/modules/git"
Expand Down Expand Up @@ -99,4 +100,22 @@ func newGit() {
git.BranchesRangeSize = Git.BranchesRangeSize

log.Info(format, args...)

submoduleSection := Cfg.Section("git.submodule")
for key, nameValue := range submoduleSection.KeysHash() {
if !strings.HasPrefix(key, "MAP_NAME_") {
continue
}
if nameValue == "" {
continue
}
if !submoduleSection.HasKey("MAP_VALUE_" + key[9:]) {
log.Error("Missing value for submodule map: %s", key)
continue
}
valueValue := submoduleSection.Key("MAP_VALUE_" + key[9:]).MustString("")
if valueValue != "" {
git.SubModuleMap[nameValue] = valueValue
}
}
}

0 comments on commit ecb943b

Please sign in to comment.