Merge branch 'master' into add-api-issues-subscriptions

This commit is contained in:
6543
2019-10-31 16:45:09 +01:00
committed by GitHub
78 changed files with 6130 additions and 3797 deletions

View File

@@ -596,6 +596,8 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Get("/search", repo.Search)
})
m.Get("/repos/issues/search", repo.SearchIssues)
m.Combo("/repositories/:id", reqToken()).Get(repo.GetByID)
m.Group("/repos", func() {

View File

@@ -14,6 +14,7 @@ import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
issue_indexer "code.gitea.io/gitea/modules/indexer/issues"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/timeutil"
@@ -22,6 +23,137 @@ import (
milestone_service "code.gitea.io/gitea/services/milestone"
)
// SearchIssues searches for issues across the repositories that the user has access to
func SearchIssues(ctx *context.APIContext) {
// swagger:operation GET /repos/issues/search issue issueSearchIssues
// ---
// summary: Search for issues across the repositories that the user has access to
// produces:
// - application/json
// parameters:
// - name: state
// in: query
// description: whether issue is open or closed
// type: string
// - name: labels
// in: query
// description: comma separated list of labels. Fetch only issues that have any of this labels. Non existent labels are discarded
// type: string
// - name: page
// in: query
// description: page number of requested issues
// type: integer
// - name: q
// in: query
// description: search string
// type: string
// - name: priority_repo_id
// in: query
// description: repository to prioritize in the results
// type: integer
// format: int64
// responses:
// "200":
// "$ref": "#/responses/IssueList"
var isClosed util.OptionalBool
switch ctx.Query("state") {
case "closed":
isClosed = util.OptionalBoolTrue
case "all":
isClosed = util.OptionalBoolNone
default:
isClosed = util.OptionalBoolFalse
}
// find repos user can access (for issue search)
repoIDs := make([]int64, 0)
issueCount := 0
for page := 1; ; page++ {
repos, count, err := models.SearchRepositoryByName(&models.SearchRepoOptions{
Page: page,
PageSize: 15,
Private: true,
Keyword: "",
OwnerID: ctx.User.ID,
TopicOnly: false,
Collaborate: util.OptionalBoolNone,
UserIsAdmin: ctx.IsUserSiteAdmin(),
UserID: ctx.User.ID,
OrderBy: models.SearchOrderByRecentUpdated,
})
if err != nil {
ctx.Error(500, "SearchRepositoryByName", err)
return
}
if len(repos) == 0 {
break
}
log.Trace("Processing next %d repos of %d", len(repos), count)
for _, repo := range repos {
switch isClosed {
case util.OptionalBoolTrue:
issueCount += repo.NumClosedIssues
case util.OptionalBoolFalse:
issueCount += repo.NumOpenIssues
case util.OptionalBoolNone:
issueCount += repo.NumIssues
}
repoIDs = append(repoIDs, repo.ID)
}
}
var issues []*models.Issue
keyword := strings.Trim(ctx.Query("q"), " ")
if strings.IndexByte(keyword, 0) >= 0 {
keyword = ""
}
var issueIDs []int64
var labelIDs []int64
var err error
if len(keyword) > 0 && len(repoIDs) > 0 {
issueIDs, err = issue_indexer.SearchIssuesByKeyword(repoIDs, keyword)
}
labels := ctx.Query("labels")
if splitted := strings.Split(labels, ","); labels != "" && len(splitted) > 0 {
labelIDs, err = models.GetLabelIDsInReposByNames(repoIDs, splitted)
if err != nil {
ctx.Error(500, "GetLabelIDsInRepoByNames", err)
return
}
}
// Only fetch the issues if we either don't have a keyword or the search returned issues
// This would otherwise return all issues if no issues were found by the search.
if len(keyword) == 0 || len(issueIDs) > 0 || len(labelIDs) > 0 {
issues, err = models.Issues(&models.IssuesOptions{
RepoIDs: repoIDs,
Page: ctx.QueryInt("page"),
PageSize: setting.UI.IssuePagingNum,
IsClosed: isClosed,
IssueIDs: issueIDs,
LabelIDs: labelIDs,
SortType: "priorityrepo",
PriorityRepoID: ctx.QueryInt64("priority_repo_id"),
})
}
if err != nil {
ctx.Error(500, "Issues", err)
return
}
apiIssues := make([]*api.Issue, len(issues))
for i := range issues {
apiIssues[i] = issues[i].APIFormat()
}
ctx.SetLinkHeader(issueCount, setting.UI.IssuePagingNum)
ctx.JSON(200, &apiIssues)
}
// ListIssues list the issues of a repository
func ListIssues(ctx *context.APIContext) {
// swagger:operation GET /repos/{owner}/{repo}/issues issue issueListIssues
@@ -79,7 +211,7 @@ func ListIssues(ctx *context.APIContext) {
var labelIDs []int64
var err error
if len(keyword) > 0 {
issueIDs, err = issue_indexer.SearchIssuesByKeyword(ctx.Repo.Repository.ID, keyword)
issueIDs, err = issue_indexer.SearchIssuesByKeyword([]int64{ctx.Repo.Repository.ID}, keyword)
}
if splitted := strings.Split(ctx.Query("labels"), ","); len(splitted) > 0 {

View File

@@ -149,7 +149,7 @@ func issues(ctx *context.Context, milestoneID int64, isPullOption util.OptionalB
var issueIDs []int64
if len(keyword) > 0 {
issueIDs, err = issue_indexer.SearchIssuesByKeyword(repo.ID, keyword)
issueIDs, err = issue_indexer.SearchIssuesByKeyword([]int64{repo.ID}, keyword)
if err != nil {
ctx.ServerError("issueIndexer.Search", err)
return
@@ -778,6 +778,9 @@ func ViewIssue(ctx *context.Context) {
// Check if the user can use the dependencies
ctx.Data["CanCreateIssueDependencies"] = ctx.Repo.CanCreateIssueDependencies(ctx.User)
// check if dependencies can be created across repositories
ctx.Data["AllowCrossRepositoryDependencies"] = setting.Service.AllowCrossRepositoryDependencies
// Render comments and and fetch participants.
participants[0] = issue.Poster
for _, comment = range issue.Comments {

View File

@@ -10,6 +10,7 @@ import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/setting"
)
// AddDependency adds new dependencies
@@ -39,14 +40,14 @@ func AddDependency(ctx *context.Context) {
return
}
// Check if both issues are in the same repo
if issue.RepoID != dep.RepoID {
// Check if both issues are in the same repo if cross repository dependencies is not enabled
if issue.RepoID != dep.RepoID && !setting.Service.AllowCrossRepositoryDependencies {
ctx.Flash.Error(ctx.Tr("repo.issues.dependency.add_error_dep_not_same_repo"))
return
}
// Check if issue and dependency is the same
if dep.Index == issueIndex {
if dep.ID == issue.ID {
ctx.Flash.Error(ctx.Tr("repo.issues.dependency.add_error_same_issue"))
return
}