Skip to content

Commit 448d0a0

Browse files
committed
Refactor push mirror find and add check for updating push mirror
1 parent c3dedcf commit 448d0a0

File tree

3 files changed

+131
-27
lines changed

3 files changed

+131
-27
lines changed

models/repo/pushmirror.go

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99

1010
"code.gitea.io/gitea/models/db"
1111
"code.gitea.io/gitea/modules/log"
12+
"code.gitea.io/gitea/modules/optional"
1213
"code.gitea.io/gitea/modules/timeutil"
1314
"code.gitea.io/gitea/modules/util"
1415

@@ -96,26 +97,47 @@ func DeletePushMirrors(ctx context.Context, opts PushMirrorOptions) error {
9697
return util.NewInvalidArgumentErrorf("repoID required and must be set")
9798
}
9899

100+
type findPushMirrorOptions struct {
101+
db.ListOptions
102+
RepoID int64
103+
SyncOnCommit optional.Option[bool]
104+
}
105+
106+
func (opts findPushMirrorOptions) ToConds() builder.Cond {
107+
cond := builder.NewCond()
108+
if opts.RepoID > 0 {
109+
cond = cond.And(builder.Eq{"repo_id": opts.RepoID})
110+
}
111+
if opts.SyncOnCommit.Has() {
112+
cond = cond.And(builder.Eq{"sync_on_commit": opts.SyncOnCommit.Value()})
113+
}
114+
return cond
115+
}
116+
99117
// GetPushMirrorsByRepoID returns push-mirror information of a repository.
100118
func GetPushMirrorsByRepoID(ctx context.Context, repoID int64, listOptions db.ListOptions) ([]*PushMirror, int64, error) {
101-
sess := db.GetEngine(ctx).Where("repo_id = ?", repoID)
102-
if listOptions.Page != 0 {
103-
sess = db.SetSessionPagination(sess, &listOptions)
104-
mirrors := make([]*PushMirror, 0, listOptions.PageSize)
105-
count, err := sess.FindAndCount(&mirrors)
106-
return mirrors, count, err
119+
return db.FindAndCount[PushMirror](ctx, findPushMirrorOptions{
120+
ListOptions: listOptions,
121+
RepoID: repoID,
122+
})
123+
}
124+
125+
func GetPushMirrorByID(ctx context.Context, id int64) (*PushMirror, error) {
126+
mirror, has, err := db.GetByID[PushMirror](ctx, id)
127+
if err != nil {
128+
return nil, err
129+
} else if !has {
130+
return nil, ErrPushMirrorNotExist
107131
}
108-
mirrors := make([]*PushMirror, 0, 10)
109-
count, err := sess.FindAndCount(&mirrors)
110-
return mirrors, count, err
132+
return mirror, nil
111133
}
112134

113135
// GetPushMirrorsSyncedOnCommit returns push-mirrors for this repo that should be updated by new commits
114136
func GetPushMirrorsSyncedOnCommit(ctx context.Context, repoID int64) ([]*PushMirror, error) {
115-
mirrors := make([]*PushMirror, 0, 10)
116-
return mirrors, db.GetEngine(ctx).
117-
Where("repo_id = ? AND sync_on_commit = ?", repoID, true).
118-
Find(&mirrors)
137+
return db.Find[PushMirror](ctx, findPushMirrorOptions{
138+
RepoID: repoID,
139+
SyncOnCommit: optional.Some(true),
140+
})
119141
}
120142

121143
// PushMirrorsIterate iterates all push-mirror repositories.

routers/web/repo/setting/setting.go

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -317,15 +317,13 @@ func SettingsPost(ctx *context.Context) {
317317
return
318318
}
319319

320-
id, err := strconv.ParseInt(form.PushMirrorID, 10, 64)
320+
m, err := selectPushMirrorByForm(ctx, form, repo)
321321
if err != nil {
322-
ctx.ServerError("UpdatePushMirrorIntervalPushMirrorID", err)
322+
ctx.NotFound("", nil)
323323
return
324324
}
325-
m := &repo_model.PushMirror{
326-
ID: id,
327-
Interval: interval,
328-
}
325+
326+
m.Interval = interval
329327
if err := repo_model.UpdatePushMirrorInterval(ctx, m); err != nil {
330328
ctx.ServerError("UpdatePushMirrorInterval", err)
331329
return
@@ -1002,17 +1000,14 @@ func selectPushMirrorByForm(ctx *context.Context, form *forms.RepoSettingForm, r
10021000
return nil, err
10031001
}
10041002

1005-
pushMirrors, _, err := repo_model.GetPushMirrorsByRepoID(ctx, repo.ID, db.ListOptions{})
1003+
pushMirror, err := repo_model.GetPushMirrorByID(ctx, id)
10061004
if err != nil {
10071005
return nil, err
10081006
}
10091007

1010-
for _, m := range pushMirrors {
1011-
if m.ID == id {
1012-
m.Repo = repo
1013-
return m, nil
1014-
}
1008+
if pushMirror.RepoID != repo.ID {
1009+
return nil, fmt.Errorf("PushMirror[%v] not associated to repository %v", id, repo)
10151010
}
1016-
1017-
return nil, fmt.Errorf("PushMirror[%v] not associated to repository %v", id, repo)
1011+
pushMirror.Repo = repo
1012+
return pushMirror, nil
10181013
}

tests/integration/mirror_push_test.go

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"net/url"
1111
"strconv"
1212
"testing"
13+
"time"
1314

1415
"code.gitea.io/gitea/models/db"
1516
repo_model "code.gitea.io/gitea/models/repo"
@@ -18,6 +19,7 @@ import (
1819
"code.gitea.io/gitea/modules/git"
1920
"code.gitea.io/gitea/modules/gitrepo"
2021
"code.gitea.io/gitea/modules/setting"
22+
"code.gitea.io/gitea/modules/test"
2123
gitea_context "code.gitea.io/gitea/services/context"
2224
"code.gitea.io/gitea/services/migrations"
2325
mirror_service "code.gitea.io/gitea/services/mirror"
@@ -119,3 +121,88 @@ func doRemovePushMirror(ctx APITestContext, address, username, password string,
119121
assert.Contains(t, flashCookie.Value, "success")
120122
}
121123
}
124+
125+
func TestRepoSettingPushMirror(t *testing.T) {
126+
defer tests.PrepareTestEnv(t)()
127+
128+
session := loginUser(t, "user2")
129+
130+
repoPrefix := "/user2/repo2"
131+
repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
132+
133+
defer test.MockVariableValue(&setting.Migrations.AllowedDomains, "127.0.0.1")()
134+
assert.NoError(t, migrations.Init())
135+
defer func() {
136+
migrations.Init()
137+
}()
138+
139+
// visit repository setting page
140+
req := NewRequest(t, "GET", repoPrefix+"/settings")
141+
resp := session.MakeRequest(t, req, http.StatusOK)
142+
htmlDoc := NewHTMLParser(t, resp.Body)
143+
144+
defer func() {
145+
// avoid dirty mirror data once test failure
146+
repo_model.DeletePushMirrors(db.DefaultContext, repo_model.PushMirrorOptions{
147+
RepoID: repo2.ID,
148+
})
149+
}()
150+
151+
onGiteaRun(t, func(t *testing.T, u *url.URL) {
152+
t.Run("Push Mirror Add", func(t *testing.T) {
153+
req = NewRequestWithValues(t, "POST", repoPrefix+"/settings", map[string]string{
154+
"_csrf": htmlDoc.GetCSRF(),
155+
"action": "push-mirror-add",
156+
"push_mirror_address": u.String() + "/user1/repo1.git",
157+
"push_mirror_interval": "0",
158+
})
159+
session.MakeRequest(t, req, http.StatusSeeOther)
160+
161+
flashCookie := session.GetCookie(gitea_context.CookieNameFlash)
162+
assert.NotNil(t, flashCookie)
163+
assert.Contains(t, flashCookie.Value, "success")
164+
165+
mirrors, cnt, err := repo_model.GetPushMirrorsByRepoID(db.DefaultContext, repo2.ID, db.ListOptions{})
166+
assert.NoError(t, err)
167+
assert.Len(t, mirrors, 1)
168+
assert.EqualValues(t, 1, cnt)
169+
assert.EqualValues(t, 0, mirrors[0].Interval)
170+
})
171+
172+
mirrors, _, _ := repo_model.GetPushMirrorsByRepoID(db.DefaultContext, repo2.ID, db.ListOptions{})
173+
174+
t.Run("Push Mirror Update", func(t *testing.T) {
175+
req := NewRequestWithValues(t, "POST", repoPrefix+"/settings", map[string]string{
176+
"_csrf": htmlDoc.GetCSRF(),
177+
"action": "push-mirror-update",
178+
"push_mirror_id": strconv.FormatInt(mirrors[0].ID, 10),
179+
"push_mirror_interval": "10m0s",
180+
})
181+
session.MakeRequest(t, req, http.StatusSeeOther)
182+
183+
mirror, err := repo_model.GetPushMirrorByID(db.DefaultContext, mirrors[0].ID)
184+
assert.NoError(t, err)
185+
assert.EqualValues(t, 10*time.Minute, mirror.Interval)
186+
187+
req = NewRequestWithValues(t, "POST", repoPrefix+"/settings", map[string]string{
188+
"_csrf": htmlDoc.GetCSRF(),
189+
"action": "push-mirror-update",
190+
"push_mirror_id": strconv.FormatInt(9999, 10), // 1 is an mirror ID which is not exist
191+
"push_mirror_interval": "10m0s",
192+
})
193+
session.MakeRequest(t, req, http.StatusNotFound)
194+
})
195+
196+
t.Run("Push Mirror Remove", func(t *testing.T) {
197+
req := NewRequestWithValues(t, "POST", repoPrefix+"/settings", map[string]string{
198+
"_csrf": htmlDoc.GetCSRF(),
199+
"action": "push-mirror-remove",
200+
"push_mirror_id": strconv.FormatInt(mirrors[0].ID, 10),
201+
})
202+
session.MakeRequest(t, req, http.StatusSeeOther)
203+
204+
_, err := repo_model.GetPushMirrorByID(db.DefaultContext, mirrors[0].ID)
205+
assert.Error(t, err)
206+
})
207+
})
208+
}

0 commit comments

Comments
 (0)