From b76846c66f4a53e2553beb2743e34cf9a3bda882 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 7 Feb 2022 15:22:10 +0800 Subject: [PATCH 01/15] Fix some mirror bugs --- models/repo/mirror.go | 6 --- modules/git/remote.go | 20 ++++++-- modules/git/url/url.go | 71 +++++++++++++++++++++++++++ modules/git/url/url_test.go | 72 ++++++++++++++++++++++++++++ modules/templates/helper.go | 29 ++++++++--- routers/web/repo/setting.go | 1 + templates/repo/header.tmpl | 3 +- templates/repo/settings/options.tmpl | 7 +-- 8 files changed, 187 insertions(+), 22 deletions(-) create mode 100644 modules/git/url/url.go create mode 100644 modules/git/url/url_test.go diff --git a/models/repo/mirror.go b/models/repo/mirror.go index 5d20b7f83343d..f2ce06255f5d1 100644 --- a/models/repo/mirror.go +++ b/models/repo/mirror.go @@ -19,12 +19,6 @@ import ( // ErrMirrorNotExist mirror does not exist error var ErrMirrorNotExist = errors.New("Mirror does not exist") -// RemoteMirrorer defines base methods for pull/push mirrors. -type RemoteMirrorer interface { - GetRepository() *Repository - GetRemoteName() string -} - // Mirror represents mirror information of a repository. type Mirror struct { ID int64 `xorm:"pk autoincr"` diff --git a/modules/git/remote.go b/modules/git/remote.go index 536b1681cecf9..6a90debcb97ab 100644 --- a/modules/git/remote.go +++ b/modules/git/remote.go @@ -6,14 +6,15 @@ package git import ( "context" - "net/url" + + "code.gitea.io/gitea/modules/git/url" ) -// GetRemoteAddress returns the url of a specific remote of the repository. -func GetRemoteAddress(ctx context.Context, repoPath, remoteName string) (*url.URL, error) { +// GetRemoteURL returns remote url of git repository in the repoPath with special remote name +func GetRemoteURL(ctx context.Context, repoPath, remoteName string) (string, error) { err := LoadGitVersion() if err != nil { - return nil, err + return "", err } var cmd *Command if CheckGitVersionAtLeast("2.7") == nil { @@ -24,11 +25,20 @@ func GetRemoteAddress(ctx context.Context, repoPath, remoteName string) (*url.UR result, _, err := cmd.RunStdString(&RunOpts{Dir: repoPath}) if err != nil { - return nil, err + return "", err } if len(result) > 0 { result = result[:len(result)-1] } + return result, nil +} + +// GetRemoteAddress returns the url of a specific remote of the repository. +func GetRemoteAddress(ctx context.Context, repoPath, remoteName string) (*url.URL, error) { + result, err := GetRemoteURL(ctx, repoPath, remoteName) + if err != nil { + return nil, err + } return url.Parse(result) } diff --git a/modules/git/url/url.go b/modules/git/url/url.go new file mode 100644 index 0000000000000..794833601ac68 --- /dev/null +++ b/modules/git/url/url.go @@ -0,0 +1,71 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package url + +import ( + "fmt" + "net/url" + "regexp" + "strings" +) + +// URL represents a git remote URL +type URL struct { + *url.URL + extraMark int // 0 no extra 1 scp 2 file path with no prefix +} + +// String returns the URL's string +func (u *URL) String() string { + switch u.extraMark { + case 0: + return u.String() + case 1: + return fmt.Sprintf("%s@%s:%s", u.User.Username(), u.Host, u.Path) + case 2: + return u.Path + default: + return "" + } +} + +var scpSyntaxRe = regexp.MustCompile(`^([a-zA-Z0-9_]+)@([a-zA-Z0-9._-]+):(.*)$`) + +// Parse parse all kinds of git remote URL +func Parse(remote string) (*URL, error) { + u, err := url.Parse(remote) + if err == nil { + extraMark := 0 + if u.Scheme == "" && u.Path != "" { + u.Scheme = "file" + extraMark = 2 + } + return &URL{URL: u, extraMark: extraMark}, nil + } + + if !strings.Contains(err.Error(), "first path segment in URL cannot contain colon") { + return nil, err + } + + if results := scpSyntaxRe.FindStringSubmatch(remote); results != nil { + return &URL{ + URL: &url.URL{ + Scheme: "ssh", + User: url.User(results[1]), + Host: results[2], + Path: results[3], + }, + extraMark: 1, + }, nil + } + + return &URL{ + URL: &url.URL{ + Scheme: "file", + Path: remote, + }, + extraMark: 2, + }, nil +} diff --git a/modules/git/url/url_test.go b/modules/git/url/url_test.go new file mode 100644 index 0000000000000..29c0d66664d05 --- /dev/null +++ b/modules/git/url/url_test.go @@ -0,0 +1,72 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package url + +import ( + "net/url" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestParseURL(t *testing.T) { + kases := []struct { + kase string + expected *URL + }{ + { + kase: "git@github.com:go-gitea/gitea.git", + expected: &URL{ + URL: &url.URL{ + Scheme: "ssh", + User: url.User("git"), + Host: "github.com", + Path: "go-gitea/gitea.git", + }, + extraMark: 1, + }, + }, + { + kase: "/repositories/go-gitea/gitea.git", + expected: &URL{ + URL: &url.URL{ + Scheme: "file", + Path: "/repositories/go-gitea/gitea.git", + }, + extraMark: 2, + }, + }, + { + kase: "https://github.com/go-gitea/gitea.git", + expected: &URL{ + URL: &url.URL{ + Scheme: "https", + Host: "github.com", + Path: "/go-gitea/gitea.git", + }, + extraMark: 0, + }, + }, + { + kase: "https://git:git@github.com/go-gitea/gitea.git", + expected: &URL{ + URL: &url.URL{ + Scheme: "https", + Host: "github.com", + User: url.UserPassword("git", "git"), + Path: "/go-gitea/gitea.git", + }, + extraMark: 0, + }, + }, + } + + for _, kase := range kases { + u, err := Parse(kase.kase) + assert.NoError(t, err) + assert.EqualValues(t, kase.expected.extraMark, u.extraMark) + assert.EqualValues(t, *kase.expected, *u) + } +} diff --git a/modules/templates/helper.go b/modules/templates/helper.go index cc0fed7442205..1c63602b022fa 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -910,20 +910,35 @@ type remoteAddress struct { Password string } -func mirrorRemoteAddress(ctx context.Context, m repo_model.RemoteMirrorer) remoteAddress { +func mirrorRemoteAddress(ctx context.Context, m *repo_model.Repository, remoteName string) remoteAddress { a := remoteAddress{} + if !m.IsMirror { + return a + } + + var remoteURL = m.OriginalURL + if remoteURL == "" { + var err error + remoteURL, err = git.GetRemoteURL(ctx, m.RepoPath(), remoteName) + if err != nil { + log.Error("GetRemoteURL %v", err) + return a + } + } - u, err := git.GetRemoteAddress(ctx, m.GetRepository().RepoPath(), m.GetRemoteName()) + u, err := url.Parse(remoteURL) if err != nil { - log.Error("GetRemoteAddress %v", err) + log.Error("giturl.Parse %v", err) return a } - if u.User != nil { - a.Username = u.User.Username() - a.Password, _ = u.User.Password() + if u.Scheme != "ssh" && u.Scheme != "file" { + if u.User != nil { + a.Username = u.User.Username() + a.Password, _ = u.User.Password() + } + u.User = nil } - u.User = nil a.Address = u.String() return a diff --git a/routers/web/repo/setting.go b/routers/web/repo/setting.go index a60bf52622160..2da41f3cf8fba 100644 --- a/routers/web/repo/setting.go +++ b/routers/web/repo/setting.go @@ -92,6 +92,7 @@ func Settings(ctx *context.Context) { return } ctx.Data["PushMirrors"] = pushMirrors + ctx.Data["Mirror"] = ctx.Repo.Mirror ctx.HTML(http.StatusOK, tplSettingsOptions) } diff --git a/templates/repo/header.tmpl b/templates/repo/header.tmpl index 2d963d67c8974..b8c4c428ea3b2 100644 --- a/templates/repo/header.tmpl +++ b/templates/repo/header.tmpl @@ -37,7 +37,8 @@ {{end}} - {{if .IsMirror}}
{{$.i18n.Tr "repo.mirror_from"}} {{if .SanitizedOriginalURL}}{{.SanitizedOriginalURL}}{{else}}{{(MirrorRemoteAddress $.Context $.Mirror).Address}}{{end}}
{{end}} + {{$address := MirrorRemoteAddress $.Context . $.Mirror.GetRemoteName}} + {{if .IsMirror}}
{{$.i18n.Tr "repo.mirror_from"}} {{$address.Address}}
{{end}} {{if .IsFork}}
{{$.i18n.Tr "repo.forked_from"}} {{.BaseRepo.FullName}}
{{end}} {{if .IsGenerated}}
{{$.i18n.Tr "repo.generated_from"}} {{.TemplateRepo.FullName}}
{{end}} diff --git a/templates/repo/settings/options.tmpl b/templates/repo/settings/options.tmpl index e2d6c5e1d5039..319f32f0c0eff 100644 --- a/templates/repo/settings/options.tmpl +++ b/templates/repo/settings/options.tmpl @@ -91,7 +91,7 @@ {{if .Repository.IsMirror}} - {{(MirrorRemoteAddress $.Context .Mirror).Address}} + {{(MirrorRemoteAddress $.Context .Repository .Mirror.GetRemoteName).Address}} {{$.i18n.Tr "repo.settings.mirror_settings.direction.pull"}} {{.Mirror.UpdatedUnix.AsTime}} @@ -119,7 +119,8 @@ - {{$address := MirrorRemoteAddress $.Context .Mirror}} + {{$originalURL := .SanitizedOriginalURL}} + {{$address := MirrorRemoteAddress $.Context .Repository .Mirror.GetRemoteName}}
@@ -168,7 +169,7 @@ {{range .PushMirrors}} - {{$address := MirrorRemoteAddress $.Context .}} + {{$address := MirrorRemoteAddress $.Context . $.Mirror.GetRemoteName}} {{$address.Address}} {{$.i18n.Tr "repo.settings.mirror_settings.direction.push"}} {{if .LastUpdateUnix}}{{.LastUpdateUnix.AsTime}}{{else}}{{$.i18n.Tr "never"}}{{end}} {{if .LastError}}
{{$.i18n.Tr "error"}}
{{end}} From 3392a1b7de2c5651c52a97c08af7c02bfe4f0b37 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 7 Feb 2022 15:30:01 +0800 Subject: [PATCH 02/15] Remove unnecessary code --- routers/web/repo/setting.go | 1 - templates/repo/settings/options.tmpl | 1 - 2 files changed, 2 deletions(-) diff --git a/routers/web/repo/setting.go b/routers/web/repo/setting.go index 2da41f3cf8fba..a60bf52622160 100644 --- a/routers/web/repo/setting.go +++ b/routers/web/repo/setting.go @@ -92,7 +92,6 @@ func Settings(ctx *context.Context) { return } ctx.Data["PushMirrors"] = pushMirrors - ctx.Data["Mirror"] = ctx.Repo.Mirror ctx.HTML(http.StatusOK, tplSettingsOptions) } diff --git a/templates/repo/settings/options.tmpl b/templates/repo/settings/options.tmpl index 319f32f0c0eff..9d76713b5d11f 100644 --- a/templates/repo/settings/options.tmpl +++ b/templates/repo/settings/options.tmpl @@ -119,7 +119,6 @@
- {{$originalURL := .SanitizedOriginalURL}} {{$address := MirrorRemoteAddress $.Context .Repository .Mirror.GetRemoteName}}
From c69de157584da14b0c52ef607c1cce28509f80d3 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 7 Feb 2022 15:31:08 +0800 Subject: [PATCH 03/15] Fix lint --- modules/templates/helper.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/templates/helper.go b/modules/templates/helper.go index 1c63602b022fa..3625ee4fd8194 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -916,7 +916,7 @@ func mirrorRemoteAddress(ctx context.Context, m *repo_model.Repository, remoteNa return a } - var remoteURL = m.OriginalURL + remoteURL := m.OriginalURL if remoteURL == "" { var err error remoteURL, err = git.GetRemoteURL(ctx, m.RepoPath(), remoteName) From eb548af191e167547c584faf11ea5f32a67ddeb9 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 7 Feb 2022 15:43:24 +0800 Subject: [PATCH 04/15] rename stdard url --- modules/git/url/url.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/modules/git/url/url.go b/modules/git/url/url.go index 794833601ac68..34e6bfe16ad74 100644 --- a/modules/git/url/url.go +++ b/modules/git/url/url.go @@ -7,13 +7,14 @@ package url import ( "fmt" "net/url" + stdurl "net/url" "regexp" "strings" ) // URL represents a git remote URL type URL struct { - *url.URL + *stdurl.URL extraMark int // 0 no extra 1 scp 2 file path with no prefix } @@ -35,7 +36,7 @@ var scpSyntaxRe = regexp.MustCompile(`^([a-zA-Z0-9_]+)@([a-zA-Z0-9._-]+):(.*)$`) // Parse parse all kinds of git remote URL func Parse(remote string) (*URL, error) { - u, err := url.Parse(remote) + u, err := stdurl.Parse(remote) if err == nil { extraMark := 0 if u.Scheme == "" && u.Path != "" { @@ -51,7 +52,7 @@ func Parse(remote string) (*URL, error) { if results := scpSyntaxRe.FindStringSubmatch(remote); results != nil { return &URL{ - URL: &url.URL{ + URL: &stdurl.URL{ Scheme: "ssh", User: url.User(results[1]), Host: results[2], @@ -62,7 +63,7 @@ func Parse(remote string) (*URL, error) { } return &URL{ - URL: &url.URL{ + URL: &stdurl.URL{ Scheme: "file", Path: remote, }, From 00451ef1a9f679a91be20af49f16d601ff663f17 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 7 Feb 2022 15:50:07 +0800 Subject: [PATCH 05/15] Allow more charactors in git ssh protocol url --- modules/git/url/url.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/git/url/url.go b/modules/git/url/url.go index 34e6bfe16ad74..b5364b9c857e7 100644 --- a/modules/git/url/url.go +++ b/modules/git/url/url.go @@ -32,7 +32,7 @@ func (u *URL) String() string { } } -var scpSyntaxRe = regexp.MustCompile(`^([a-zA-Z0-9_]+)@([a-zA-Z0-9._-]+):(.*)$`) +var scpSyntaxRe = regexp.MustCompile(`^([a-zA-Z0-9-._~]+)@([a-zA-Z0-9._-]+):(.*)$`) // Parse parse all kinds of git remote URL func Parse(remote string) (*URL, error) { From da038e4a39b3cb6c64c82d61f0b01535c7863ae8 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Tue, 8 Feb 2022 15:23:33 +0800 Subject: [PATCH 06/15] improve the detection --- modules/git/url/url.go | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/modules/git/url/url.go b/modules/git/url/url.go index b5364b9c857e7..10966adbe3d78 100644 --- a/modules/git/url/url.go +++ b/modules/git/url/url.go @@ -36,18 +36,12 @@ var scpSyntaxRe = regexp.MustCompile(`^([a-zA-Z0-9-._~]+)@([a-zA-Z0-9._-]+):(.*) // Parse parse all kinds of git remote URL func Parse(remote string) (*URL, error) { - u, err := stdurl.Parse(remote) - if err == nil { - extraMark := 0 - if u.Scheme == "" && u.Path != "" { - u.Scheme = "file" - extraMark = 2 + if strings.Contains(remote, "://") { + u, err := stdurl.Parse(remote) + if err != nil { + return nil, err } - return &URL{URL: u, extraMark: extraMark}, nil - } - - if !strings.Contains(err.Error(), "first path segment in URL cannot contain colon") { - return nil, err + return &URL{URL: u}, nil } if results := scpSyntaxRe.FindStringSubmatch(remote); results != nil { From 52b6d13a653f3638b9c5685831557882886d816a Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 4 Apr 2022 21:39:47 +0800 Subject: [PATCH 07/15] support ipv6 for git url parse --- modules/git/remote.go | 6 +-- modules/git/url/url.go | 66 +++++++++++++++-------- modules/git/url/url_test.go | 103 ++++++++++++++++++++++++++++++++---- 3 files changed, 141 insertions(+), 34 deletions(-) diff --git a/modules/git/remote.go b/modules/git/remote.go index 6a90debcb97ab..cf45d3fb36d63 100644 --- a/modules/git/remote.go +++ b/modules/git/remote.go @@ -7,7 +7,7 @@ package git import ( "context" - "code.gitea.io/gitea/modules/git/url" + giturl "code.gitea.io/gitea/modules/git/url" ) // GetRemoteURL returns remote url of git repository in the repoPath with special remote name @@ -35,10 +35,10 @@ func GetRemoteURL(ctx context.Context, repoPath, remoteName string) (string, err } // GetRemoteAddress returns the url of a specific remote of the repository. -func GetRemoteAddress(ctx context.Context, repoPath, remoteName string) (*url.URL, error) { +func GetRemoteAddress(ctx context.Context, repoPath, remoteName string) (*giturl.GitURL, error) { result, err := GetRemoteURL(ctx, repoPath, remoteName) if err != nil { return nil, err } - return url.Parse(result) + return giturl.Parse(result) } diff --git a/modules/git/url/url.go b/modules/git/url/url.go index 10966adbe3d78..e8843026e55ad 100644 --- a/modules/git/url/url.go +++ b/modules/git/url/url.go @@ -6,20 +6,27 @@ package url import ( "fmt" - "net/url" stdurl "net/url" - "regexp" "strings" ) -// URL represents a git remote URL -type URL struct { +// 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 no extra 1 scp 2 file path with no prefix } // String returns the URL's string -func (u *URL) String() string { +func (u *GitURL) String() string { switch u.extraMark { case 0: return u.String() @@ -32,31 +39,48 @@ func (u *URL) String() string { } } -var scpSyntaxRe = regexp.MustCompile(`^([a-zA-Z0-9-._~]+)@([a-zA-Z0-9._-]+):(.*)$`) - -// Parse parse all kinds of git remote URL -func Parse(remote string) (*URL, error) { +// Parse parse all kinds of git URL +func Parse(remote string) (*GitURL, error) { if strings.Contains(remote, "://") { u, err := stdurl.Parse(remote) if err != nil { return nil, err } - return &URL{URL: u}, nil - } - - if results := scpSyntaxRe.FindStringSubmatch(remote); results != nil { - return &URL{ - URL: &stdurl.URL{ - Scheme: "ssh", - User: url.User(results[1]), - Host: results[2], - Path: results[3], - }, + 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 = remote[lastIndex:i] + 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 &URL{ + return &GitURL{ URL: &stdurl.URL{ Scheme: "file", Path: remote, diff --git a/modules/git/url/url_test.go b/modules/git/url/url_test.go index 29c0d66664d05..4a9de1b7861c2 100644 --- a/modules/git/url/url_test.go +++ b/modules/git/url/url_test.go @@ -11,14 +11,50 @@ import ( "github.com/stretchr/testify/assert" ) -func TestParseURL(t *testing.T) { +func TestParseGitURLs(t *testing.T) { kases := []struct { kase string - expected *URL + expected *GitURL }{ + { + kase: "git@127.0.0.1:go-gitea/gitea.git", + expected: &GitURL{ + URL: &url.URL{ + Scheme: "ssh", + User: url.User("git"), + Host: "127.0.0.1", + Path: "go-gitea/gitea.git", + }, + extraMark: 1, + }, + }, + { + kase: "git@[fe80:14fc:cec5:c174:d88%2510]:go-gitea/gitea.git", + expected: &GitURL{ + URL: &url.URL{ + Scheme: "ssh", + User: url.User("git"), + Host: "[fe80:14fc:cec5:c174:d88%2510]", + Path: "go-gitea/gitea.git", + }, + extraMark: 1, + }, + }, + { + kase: "git@[::1]:go-gitea/gitea.git", + expected: &GitURL{ + URL: &url.URL{ + Scheme: "ssh", + User: url.User("git"), + Host: "[::1]", + Path: "go-gitea/gitea.git", + }, + extraMark: 1, + }, + }, { kase: "git@github.com:go-gitea/gitea.git", - expected: &URL{ + expected: &GitURL{ URL: &url.URL{ Scheme: "ssh", User: url.User("git"), @@ -28,9 +64,33 @@ func TestParseURL(t *testing.T) { extraMark: 1, }, }, + { + kase: "ssh://git@github.com/go-gitea/gitea.git", + expected: &GitURL{ + URL: &url.URL{ + Scheme: "ssh", + User: url.User("git"), + Host: "github.com", + Path: "/go-gitea/gitea.git", + }, + extraMark: 0, + }, + }, + { + kase: "ssh://git@[::1]/go-gitea/gitea.git", + expected: &GitURL{ + URL: &url.URL{ + Scheme: "ssh", + User: url.User("git"), + Host: "[::1]", + Path: "/go-gitea/gitea.git", + }, + extraMark: 0, + }, + }, { kase: "/repositories/go-gitea/gitea.git", - expected: &URL{ + expected: &GitURL{ URL: &url.URL{ Scheme: "file", Path: "/repositories/go-gitea/gitea.git", @@ -38,9 +98,19 @@ func TestParseURL(t *testing.T) { extraMark: 2, }, }, + { + kase: "file:///repositories/go-gitea/gitea.git", + expected: &GitURL{ + URL: &url.URL{ + Scheme: "file", + Path: "/repositories/go-gitea/gitea.git", + }, + extraMark: 0, + }, + }, { kase: "https://github.com/go-gitea/gitea.git", - expected: &URL{ + expected: &GitURL{ URL: &url.URL{ Scheme: "https", Host: "github.com", @@ -51,7 +121,7 @@ func TestParseURL(t *testing.T) { }, { kase: "https://git:git@github.com/go-gitea/gitea.git", - expected: &URL{ + expected: &GitURL{ URL: &url.URL{ Scheme: "https", Host: "github.com", @@ -61,12 +131,25 @@ func TestParseURL(t *testing.T) { extraMark: 0, }, }, + { + kase: "git://github.com/go-gitea/gitea.git", + expected: &GitURL{ + URL: &url.URL{ + Scheme: "git", + Host: "github.com", + Path: "/go-gitea/gitea.git", + }, + extraMark: 0, + }, + }, } for _, kase := range kases { - u, err := Parse(kase.kase) - assert.NoError(t, err) - assert.EqualValues(t, kase.expected.extraMark, u.extraMark) - assert.EqualValues(t, *kase.expected, *u) + t.Run(kase.kase, func(t *testing.T) { + u, err := Parse(kase.kase) + assert.NoError(t, err) + assert.EqualValues(t, kase.expected.extraMark, u.extraMark) + assert.EqualValues(t, *kase.expected, *u) + }) } } From bac353dfcb64cee55054101f51170b95099f9d2d Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 4 Apr 2022 22:13:25 +0800 Subject: [PATCH 08/15] Fix bug --- routers/web/repo/setting.go | 14 ++++++++------ services/mirror/mirror_pull.go | 1 + 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/routers/web/repo/setting.go b/routers/web/repo/setting.go index a60bf52622160..f7e5a901da7bf 100644 --- a/routers/web/repo/setting.go +++ b/routers/web/repo/setting.go @@ -202,22 +202,24 @@ func SettingsPost(ctx *context.Context) { } } - u, _ := git.GetRemoteAddress(ctx, ctx.Repo.Repository.RepoPath(), ctx.Repo.Mirror.GetRemoteName()) + u, err := git.GetRemoteAddress(ctx, ctx.Repo.Repository.RepoPath(), ctx.Repo.Mirror.GetRemoteName()) + if err != nil { + ctx.Data["Err_MirrorAddress"] = true + handleSettingRemoteAddrError(ctx, err, form) + return + } if u.User != nil && form.MirrorPassword == "" && form.MirrorUsername == u.User.Username() { form.MirrorPassword, _ = u.User.Password() } - address, err := forms.ParseRemoteAddr(form.MirrorAddress, form.MirrorUsername, form.MirrorPassword) - if err == nil { - err = migrations.IsMigrateURLAllowed(address, ctx.Doer) - } + err = migrations.IsMigrateURLAllowed(u.String(), ctx.Doer) if err != nil { ctx.Data["Err_MirrorAddress"] = true handleSettingRemoteAddrError(ctx, err, form) return } - if err := mirror_service.UpdateAddress(ctx, ctx.Repo.Mirror, address); err != nil { + if err := mirror_service.UpdateAddress(ctx, ctx.Repo.Mirror, u.String()); err != nil { ctx.ServerError("UpdateAddress", err) return } diff --git a/services/mirror/mirror_pull.go b/services/mirror/mirror_pull.go index c51483821bd65..ee5d6986b66f3 100644 --- a/services/mirror/mirror_pull.go +++ b/services/mirror/mirror_pull.go @@ -214,6 +214,7 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo remoteAddr, remoteErr := git.GetRemoteAddress(ctx, repoPath, m.GetRemoteName()) if remoteErr != nil { log.Error("SyncMirrors [repo: %-v]: GetRemoteAddress Error %v", m.Repo, remoteErr) + return nil, false } stdoutBuilder := strings.Builder{} From 7bc026d977f9728900de9b52542880edc106fc4b Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 25 Apr 2022 09:45:17 +0800 Subject: [PATCH 09/15] Fix template --- templates/repo/header.tmpl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/templates/repo/header.tmpl b/templates/repo/header.tmpl index b8c4c428ea3b2..cfac37cd115b0 100644 --- a/templates/repo/header.tmpl +++ b/templates/repo/header.tmpl @@ -37,8 +37,9 @@ {{end}}
+ {{if .IsMirror}} {{$address := MirrorRemoteAddress $.Context . $.Mirror.GetRemoteName}} - {{if .IsMirror}}
{{$.i18n.Tr "repo.mirror_from"}} {{$address.Address}}
{{end}} +
{{$.i18n.Tr "repo.mirror_from"}} {{$address.Address}}
{{end}} {{if .IsFork}}
{{$.i18n.Tr "repo.forked_from"}} {{.BaseRepo.FullName}}
{{end}} {{if .IsGenerated}}
{{$.i18n.Tr "repo.generated_from"}} {{.TemplateRepo.FullName}}
{{end}} From e871985c21b290ac552515373982a3adfa804c9e Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 25 Apr 2022 13:49:50 +0800 Subject: [PATCH 10/15] Fix bug --- modules/git/url/url.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/git/url/url.go b/modules/git/url/url.go index e8843026e55ad..bd6e8bdd2b75e 100644 --- a/modules/git/url/url.go +++ b/modules/git/url/url.go @@ -29,7 +29,7 @@ type GitURL struct { func (u *GitURL) String() string { switch u.extraMark { case 0: - return u.String() + return u.URL.String() case 1: return fmt.Sprintf("%s@%s:%s", u.User.Username(), u.Host, u.Path) case 2: From 8e92e5deeb052fee6b3188794926a21cdc7571c7 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 25 Apr 2022 21:35:08 +0800 Subject: [PATCH 11/15] fix template --- templates/repo/settings/options.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/repo/settings/options.tmpl b/templates/repo/settings/options.tmpl index 9d76713b5d11f..c4f8d15b483bd 100644 --- a/templates/repo/settings/options.tmpl +++ b/templates/repo/settings/options.tmpl @@ -168,7 +168,7 @@ {{range .PushMirrors}} - {{$address := MirrorRemoteAddress $.Context . $.Mirror.GetRemoteName}} + {{$address := MirrorRemoteAddress $.Context . $.GetRemoteName}} {{$address.Address}} {{$.i18n.Tr "repo.settings.mirror_settings.direction.push"}} {{if .LastUpdateUnix}}{{.LastUpdateUnix.AsTime}}{{else}}{{$.i18n.Tr "never"}}{{end}} {{if .LastError}}
{{$.i18n.Tr "error"}}
{{end}} From d8a7456d1eb53f31d9511ebf87870d4c5192bd1b Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Thu, 12 May 2022 14:59:55 +0800 Subject: [PATCH 12/15] Fix tmpl --- modules/templates/helper.go | 3 ++- templates/repo/settings/options.tmpl | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/templates/helper.go b/modules/templates/helper.go index 3625ee4fd8194..f143579ceadc3 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -31,6 +31,7 @@ import ( "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/emoji" "code.gitea.io/gitea/modules/git" + giturl "code.gitea.io/gitea/modules/git/url" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/markup" @@ -926,7 +927,7 @@ func mirrorRemoteAddress(ctx context.Context, m *repo_model.Repository, remoteNa } } - u, err := url.Parse(remoteURL) + u, err := giturl.Parse(remoteURL) if err != nil { log.Error("giturl.Parse %v", err) return a diff --git a/templates/repo/settings/options.tmpl b/templates/repo/settings/options.tmpl index c4f8d15b483bd..be2a0eb35da03 100644 --- a/templates/repo/settings/options.tmpl +++ b/templates/repo/settings/options.tmpl @@ -168,7 +168,7 @@ {{range .PushMirrors}} - {{$address := MirrorRemoteAddress $.Context . $.GetRemoteName}} + {{$address := MirrorRemoteAddress $.Context $.Repository $.GetRemoteName}} {{$address.Address}} {{$.i18n.Tr "repo.settings.mirror_settings.direction.push"}} {{if .LastUpdateUnix}}{{.LastUpdateUnix.AsTime}}{{else}}{{$.i18n.Tr "never"}}{{end}} {{if .LastError}}
{{$.i18n.Tr "error"}}
{{end}} From ebd54a8be1c809815215d8db82d46ccafd9d60e9 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Thu, 12 May 2022 15:05:06 +0800 Subject: [PATCH 13/15] Fix tmpl --- templates/repo/settings/options.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/repo/settings/options.tmpl b/templates/repo/settings/options.tmpl index be2a0eb35da03..d5fb585384a21 100644 --- a/templates/repo/settings/options.tmpl +++ b/templates/repo/settings/options.tmpl @@ -168,7 +168,7 @@ {{range .PushMirrors}} - {{$address := MirrorRemoteAddress $.Context $.Repository $.GetRemoteName}} + {{$address := MirrorRemoteAddress $.Context $.Repository .GetRemoteName}} {{$address.Address}} {{$.i18n.Tr "repo.settings.mirror_settings.direction.push"}} {{if .LastUpdateUnix}}{{.LastUpdateUnix.AsTime}}{{else}}{{$.i18n.Tr "never"}}{{end}} {{if .LastError}}
{{$.i18n.Tr "error"}}
{{end}} From 74dfb17898e6d4079440b3beace28480349df10f Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Tue, 17 May 2022 00:08:44 +0800 Subject: [PATCH 14/15] Fix parse ssh with interface --- modules/git/url/url.go | 2 +- modules/git/url/url_test.go | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/modules/git/url/url.go b/modules/git/url/url.go index bd6e8bdd2b75e..195323c623e1a 100644 --- a/modules/git/url/url.go +++ b/modules/git/url/url.go @@ -61,7 +61,7 @@ func Parse(remote string) (*GitURL, error) { lastIndex = i + 1 case ':': if !squareBrackets { - url.Host = remote[lastIndex:i] + url.Host = strings.Replace(remote[lastIndex:i], "%25", "%", -1) if len(remote) <= i+1 { return nil, ErrWrongURLFormat{URL: remote} } diff --git a/modules/git/url/url_test.go b/modules/git/url/url_test.go index 4a9de1b7861c2..611bef8672740 100644 --- a/modules/git/url/url_test.go +++ b/modules/git/url/url_test.go @@ -34,7 +34,7 @@ func TestParseGitURLs(t *testing.T) { URL: &url.URL{ Scheme: "ssh", User: url.User("git"), - Host: "[fe80:14fc:cec5:c174:d88%2510]", + Host: "[fe80:14fc:cec5:c174:d88%10]", Path: "go-gitea/gitea.git", }, extraMark: 1, @@ -131,6 +131,18 @@ func TestParseGitURLs(t *testing.T) { extraMark: 0, }, }, + { + kase: "https://[fe80:14fc:cec5:c174:d88%2510]:20/go-gitea/gitea.git", + expected: &GitURL{ + URL: &url.URL{ + Scheme: "https", + Host: "[fe80:14fc:cec5:c174:d88%10]:20", + Path: "/go-gitea/gitea.git", + }, + extraMark: 0, + }, + }, + { kase: "git://github.com/go-gitea/gitea.git", expected: &GitURL{ From df5d00eb72e60431bf38fe38f764d69058d4fa37 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Thu, 26 May 2022 14:35:44 +0800 Subject: [PATCH 15/15] Rename functions name --- modules/git/remote.go | 12 ++++++------ modules/git/url/url.go | 2 +- modules/templates/helper.go | 2 +- routers/web/repo/setting.go | 2 +- services/mirror/mirror_pull.go | 4 ++-- services/mirror/mirror_push.go | 4 ++-- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/modules/git/remote.go b/modules/git/remote.go index cf45d3fb36d63..08a9b5e6c0834 100644 --- a/modules/git/remote.go +++ b/modules/git/remote.go @@ -10,8 +10,8 @@ import ( giturl "code.gitea.io/gitea/modules/git/url" ) -// GetRemoteURL returns remote url of git repository in the repoPath with special remote name -func GetRemoteURL(ctx context.Context, repoPath, remoteName string) (string, error) { +// GetRemoteAddress returns remote url of git repository in the repoPath with special remote name +func GetRemoteAddress(ctx context.Context, repoPath, remoteName string) (string, error) { err := LoadGitVersion() if err != nil { return "", err @@ -34,11 +34,11 @@ func GetRemoteURL(ctx context.Context, repoPath, remoteName string) (string, err return result, nil } -// GetRemoteAddress returns the url of a specific remote of the repository. -func GetRemoteAddress(ctx context.Context, repoPath, remoteName string) (*giturl.GitURL, error) { - result, err := GetRemoteURL(ctx, repoPath, remoteName) +// GetRemoteURL returns the url of a specific remote of the repository. +func GetRemoteURL(ctx context.Context, repoPath, remoteName string) (*giturl.GitURL, error) { + addr, err := GetRemoteAddress(ctx, repoPath, remoteName) if err != nil { return nil, err } - return giturl.Parse(result) + return giturl.Parse(addr) } diff --git a/modules/git/url/url.go b/modules/git/url/url.go index 195323c623e1a..b41cfab7efb29 100644 --- a/modules/git/url/url.go +++ b/modules/git/url/url.go @@ -61,7 +61,7 @@ func Parse(remote string) (*GitURL, error) { lastIndex = i + 1 case ':': if !squareBrackets { - url.Host = strings.Replace(remote[lastIndex:i], "%25", "%", -1) + url.Host = strings.ReplaceAll(remote[lastIndex:i], "%25", "%") if len(remote) <= i+1 { return nil, ErrWrongURLFormat{URL: remote} } diff --git a/modules/templates/helper.go b/modules/templates/helper.go index f143579ceadc3..b08ddf9c8e28f 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -920,7 +920,7 @@ func mirrorRemoteAddress(ctx context.Context, m *repo_model.Repository, remoteNa remoteURL := m.OriginalURL if remoteURL == "" { var err error - remoteURL, err = git.GetRemoteURL(ctx, m.RepoPath(), remoteName) + remoteURL, err = git.GetRemoteAddress(ctx, m.RepoPath(), remoteName) if err != nil { log.Error("GetRemoteURL %v", err) return a diff --git a/routers/web/repo/setting.go b/routers/web/repo/setting.go index f7e5a901da7bf..c862e5ba73639 100644 --- a/routers/web/repo/setting.go +++ b/routers/web/repo/setting.go @@ -202,7 +202,7 @@ func SettingsPost(ctx *context.Context) { } } - u, err := git.GetRemoteAddress(ctx, ctx.Repo.Repository.RepoPath(), ctx.Repo.Mirror.GetRemoteName()) + u, err := git.GetRemoteURL(ctx, ctx.Repo.Repository.RepoPath(), ctx.Repo.Mirror.GetRemoteName()) if err != nil { ctx.Data["Err_MirrorAddress"] = true handleSettingRemoteAddrError(ctx, err, form) diff --git a/services/mirror/mirror_pull.go b/services/mirror/mirror_pull.go index ee5d6986b66f3..1340cabc8c41c 100644 --- a/services/mirror/mirror_pull.go +++ b/services/mirror/mirror_pull.go @@ -211,7 +211,7 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo } gitArgs = append(gitArgs, m.GetRemoteName()) - remoteAddr, remoteErr := git.GetRemoteAddress(ctx, repoPath, m.GetRemoteName()) + remoteURL, remoteErr := git.GetRemoteURL(ctx, repoPath, m.GetRemoteName()) if remoteErr != nil { log.Error("SyncMirrors [repo: %-v]: GetRemoteAddress Error %v", m.Repo, remoteErr) return nil, false @@ -293,7 +293,7 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo if m.LFS && setting.LFS.StartServer { log.Trace("SyncMirrors [repo: %-v]: syncing LFS objects...", m.Repo) - endpoint := lfs.DetermineEndpoint(remoteAddr.String(), m.LFSEndpoint) + endpoint := lfs.DetermineEndpoint(remoteURL.String(), m.LFSEndpoint) lfsClient := lfs.NewClient(endpoint, nil) if err = repo_module.StoreMissingLfsObjectsInRepository(ctx, m.Repo, gitRepo, lfsClient); err != nil { log.Error("SyncMirrors [repo: %-v]: failed to synchronize LFS objects for repository: %v", m.Repo, err) diff --git a/services/mirror/mirror_push.go b/services/mirror/mirror_push.go index 138ebb737b235..2927bed72b279 100644 --- a/services/mirror/mirror_push.go +++ b/services/mirror/mirror_push.go @@ -131,7 +131,7 @@ func runPushSync(ctx context.Context, m *repo_model.PushMirror) error { timeout := time.Duration(setting.Git.Timeout.Mirror) * time.Second performPush := func(path string) error { - remoteAddr, err := git.GetRemoteAddress(ctx, path, m.RemoteName) + remoteURL, err := git.GetRemoteURL(ctx, path, m.RemoteName) if err != nil { log.Error("GetRemoteAddress(%s) Error %v", path, err) return errors.New("Unexpected error") @@ -147,7 +147,7 @@ func runPushSync(ctx context.Context, m *repo_model.PushMirror) error { } defer gitRepo.Close() - endpoint := lfs.DetermineEndpoint(remoteAddr.String(), "") + endpoint := lfs.DetermineEndpoint(remoteURL.String(), "") lfsClient := lfs.NewClient(endpoint, nil) if err := pushAllLFSObjects(ctx, gitRepo, lfsClient); err != nil { return util.SanitizeErrorCredentialURLs(err)