Skip to content

Commit 8a97ad1

Browse files
committed
fix
1 parent 70a5b58 commit 8a97ad1

File tree

4 files changed

+29
-86
lines changed

4 files changed

+29
-86
lines changed

routers/api/v1/repo/issue.go

Lines changed: 6 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"code.gitea.io/gitea/modules/setting"
2525
api "code.gitea.io/gitea/modules/structs"
2626
"code.gitea.io/gitea/modules/timeutil"
27+
"code.gitea.io/gitea/modules/util"
2728
"code.gitea.io/gitea/modules/web"
2829
"code.gitea.io/gitea/routers/api/v1/utils"
2930
"code.gitea.io/gitea/routers/common"
@@ -32,43 +33,6 @@ import (
3233
issue_service "code.gitea.io/gitea/services/issue"
3334
)
3435

35-
// ErrOwnerOrgRequired represents an error when owner organisation is required for filtering on team
36-
type ErrOwnerOrgRequired struct{}
37-
38-
// IsErrOwnerOrgRequired checks if an error is an ErrOwnerOrgRequired
39-
func IsErrOwnerOrgRequired(err error) bool {
40-
_, ok := err.(ErrOwnerOrgRequired)
41-
return ok
42-
}
43-
44-
func (err ErrOwnerOrgRequired) Error() string {
45-
return "owner organisation is required for filtering on team"
46-
}
47-
48-
// parseIssueIsClosed parses the "state" query parameter and returns the corresponding isClosed option
49-
func parseIssueIsClosed(ctx *context.APIContext) optional.Option[bool] {
50-
switch ctx.FormString("state") {
51-
case "closed":
52-
return optional.Some(true)
53-
case "all":
54-
return optional.None[bool]()
55-
default:
56-
return optional.Some(false)
57-
}
58-
}
59-
60-
// parseIssueIsPull parses the "type" query parameter and returns the corresponding isPull option
61-
func parseIssueIsPull(ctx *context.APIContext) optional.Option[bool] {
62-
switch ctx.FormString("type") {
63-
case "pulls":
64-
return optional.Some(true)
65-
case "issues":
66-
return optional.Some(false)
67-
default:
68-
return optional.None[bool]()
69-
}
70-
}
71-
7236
// buildSearchIssuesRepoIDs builds the list of repository IDs for issue search based on query parameters.
7337
// It returns repoIDs, allPublic flag, and any error that occurred.
7438
func buildSearchIssuesRepoIDs(ctx *context.APIContext) ([]int64, bool, error) {
@@ -101,7 +65,7 @@ func buildSearchIssuesRepoIDs(ctx *context.APIContext) ([]int64, bool, error) {
10165
}
10266
if ctx.FormString("team") != "" {
10367
if ctx.FormString("owner") == "" {
104-
return nil, false, ErrOwnerOrgRequired{}
68+
return nil, false, util.NewInvalidArgumentErrorf("owner organisation is required for filtering on team")
10569
}
10670
team, err := organization.GetTeam(ctx, opts.OwnerID, ctx.FormString("team"))
10771
if err != nil {
@@ -230,11 +194,11 @@ func SearchIssues(ctx *context.APIContext) {
230194
return
231195
}
232196

233-
isClosed := parseIssueIsClosed(ctx)
197+
isClosed := common.ParseIssueFilterStateIsClosed(ctx.FormString("state"))
234198

235199
repoIDs, allPublic, err := buildSearchIssuesRepoIDs(ctx)
236200
if err != nil {
237-
if user_model.IsErrUserNotExist(err) || organization.IsErrTeamNotExist(err) || IsErrOwnerOrgRequired(err) {
201+
if errors.Is(err, util.ErrNotExist) || errors.Is(err, util.ErrInvalidArgument) {
238202
ctx.APIError(http.StatusBadRequest, err)
239203
} else {
240204
ctx.APIErrorInternal(err)
@@ -247,7 +211,7 @@ func SearchIssues(ctx *context.APIContext) {
247211
keyword = ""
248212
}
249213

250-
isPull := parseIssueIsPull(ctx)
214+
isPull := common.ParseIssueFilterTypeIsPull(ctx.FormString("type"))
251215

252216
var includedAnyLabels []int64
253217
{
@@ -430,16 +394,7 @@ func ListIssues(ctx *context.APIContext) {
430394
return
431395
}
432396

433-
var isClosed optional.Option[bool]
434-
switch ctx.FormString("state") {
435-
case "closed":
436-
isClosed = optional.Some(true)
437-
case "all":
438-
isClosed = optional.None[bool]()
439-
default:
440-
isClosed = optional.Some(false)
441-
}
442-
397+
isClosed := common.ParseIssueFilterStateIsClosed(ctx.FormString("state"))
443398
keyword := ctx.FormTrim("q")
444399
if strings.IndexByte(keyword, 0) >= 0 {
445400
keyword = ""

routers/api/v1/repo/milestone.go

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010

1111
"code.gitea.io/gitea/models/db"
1212
issues_model "code.gitea.io/gitea/models/issues"
13-
"code.gitea.io/gitea/modules/optional"
1413
api "code.gitea.io/gitea/modules/structs"
1514
"code.gitea.io/gitea/modules/timeutil"
1615
"code.gitea.io/gitea/modules/web"
@@ -60,12 +59,7 @@ func ListMilestones(ctx *context.APIContext) {
6059
// "404":
6160
// "$ref": "#/responses/notFound"
6261

63-
state := api.StateType(ctx.FormString("state"))
64-
var isClosed optional.Option[bool]
65-
switch state {
66-
case api.StateClosed, api.StateOpen:
67-
isClosed = optional.Some(state == api.StateClosed)
68-
}
62+
isClosed := common.ParseIssueFilterStateIsClosed(ctx.FormString("state"))
6963

7064
milestones, total, err := db.FindAndCount[issues_model.Milestone](ctx, issues_model.FindMilestoneOptions{
7165
ListOptions: utils.GetListOptions(ctx),

routers/common/issue_filter.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2025 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package common
5+
6+
import (
7+
"code.gitea.io/gitea/modules/optional"
8+
)
9+
10+
func ParseIssueFilterStateIsClosed(state string) optional.Option[bool] {
11+
return optional.FromMapLookup(map[string]bool{"closed": true, "open": false, "": false}, state)
12+
}
13+
14+
func ParseIssueFilterTypeIsPull(typ string) optional.Option[bool] {
15+
return optional.FromMapLookup(map[string]bool{"pulls": true, "issues": false, "": false}, typ)
16+
}

routers/web/repo/issue_list.go

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"code.gitea.io/gitea/modules/optional"
2626
"code.gitea.io/gitea/modules/setting"
2727
"code.gitea.io/gitea/modules/util"
28+
"code.gitea.io/gitea/routers/common"
2829
"code.gitea.io/gitea/routers/web/shared/issue"
2930
shared_user "code.gitea.io/gitea/routers/web/shared/user"
3031
"code.gitea.io/gitea/services/context"
@@ -45,15 +46,7 @@ func SearchIssues(ctx *context.Context) {
4546
return
4647
}
4748

48-
var isClosed optional.Option[bool]
49-
switch ctx.FormString("state") {
50-
case "closed":
51-
isClosed = optional.Some(true)
52-
case "all":
53-
isClosed = optional.None[bool]()
54-
default:
55-
isClosed = optional.Some(false)
56-
}
49+
isClosed := common.ParseIssueFilterStateIsClosed(ctx.FormString("state"))
5750

5851
var (
5952
repoIDs []int64
@@ -268,15 +261,7 @@ func SearchRepoIssuesJSON(ctx *context.Context) {
268261
return
269262
}
270263

271-
var isClosed optional.Option[bool]
272-
switch ctx.FormString("state") {
273-
case "closed":
274-
isClosed = optional.Some(true)
275-
case "all":
276-
isClosed = optional.None[bool]()
277-
default:
278-
isClosed = optional.Some(false)
279-
}
264+
isClosed := common.ParseIssueFilterStateIsClosed(ctx.FormString("state"))
280265

281266
keyword := ctx.FormTrim("q")
282267
if strings.IndexByte(keyword, 0) >= 0 {
@@ -580,17 +565,10 @@ func prepareIssueFilterAndList(ctx *context.Context, milestoneID, projectID int6
580565
}
581566
}
582567

583-
var isShowClosed optional.Option[bool]
584-
switch ctx.FormString("state") {
585-
case "closed":
586-
isShowClosed = optional.Some(true)
587-
case "all":
588-
isShowClosed = optional.None[bool]()
589-
default:
590-
isShowClosed = optional.Some(false)
591-
}
568+
isShowClosed := common.ParseIssueFilterStateIsClosed(ctx.FormString("state"))
569+
592570
// if there are closed issues and no open issues, default to showing all issues
593-
if len(ctx.FormString("state")) == 0 && issueStats.OpenCount == 0 && issueStats.ClosedCount != 0 {
571+
if ctx.FormString("state") == "" && issueStats.OpenCount == 0 && issueStats.ClosedCount != 0 {
594572
isShowClosed = optional.None[bool]()
595573
}
596574

0 commit comments

Comments
 (0)