@@ -203,13 +203,26 @@ func GetLabelInRepoByName(repoID int64, labelName string) (*Label, error) { | |||
return getLabelInRepoByName(x, repoID, labelName) | |||
} | |||
// GetLabelIDsInRepoByNames returns a list of labelIDs by names in a given | |||
// repository. | |||
// it silently ignores label names that do not belong to the repository. | |||
func GetLabelIDsInRepoByNames(repoID int64, labelNames []string) ([]int64, error) { | |||
labelIDs := make([]int64, 0, len(labelNames)) | |||
return labelIDs, x.Table("label"). | |||
Where("repo_id = ?", repoID). | |||
In("name", labelNames). | |||
Asc("name"). | |||
Cols("id"). | |||
Find(&labelIDs) | |||
} | |||
// GetLabelInRepoByID returns a label by ID in given repository. | |||
func GetLabelInRepoByID(repoID, labelID int64) (*Label, error) { | |||
return getLabelInRepoByID(x, repoID, labelID) | |||
} | |||
// GetLabelsInRepoByIDs returns a list of labels by IDs in given repository, | |||
// it silently ignores label IDs that are not belong to the repository. | |||
// it silently ignores label IDs that do not belong to the repository. | |||
func GetLabelsInRepoByIDs(repoID int64, labelIDs []int64) ([]*Label, error) { | |||
labels := make([]*Label, 0, len(labelIDs)) | |||
return labels, x. |
@@ -81,6 +81,30 @@ func TestGetLabelInRepoByName(t *testing.T) { | |||
assert.True(t, IsErrLabelNotExist(err)) | |||
} | |||
func TestGetLabelInRepoByNames(t *testing.T) { | |||
assert.NoError(t, PrepareTestDatabase()) | |||
labelIDs, err := GetLabelIDsInRepoByNames(1, []string{"label1", "label2"}) | |||
assert.NoError(t, err) | |||
assert.Len(t, labelIDs, 2) | |||
assert.Equal(t, int64(1), labelIDs[0]) | |||
assert.Equal(t, int64(2), labelIDs[1]) | |||
} | |||
func TestGetLabelInRepoByNamesDiscardsNonExistentLabels(t *testing.T) { | |||
assert.NoError(t, PrepareTestDatabase()) | |||
// label3 doesn't exists.. See labels.yml | |||
labelIDs, err := GetLabelIDsInRepoByNames(1, []string{"label1", "label2", "label3"}) | |||
assert.NoError(t, err) | |||
assert.Len(t, labelIDs, 2) | |||
assert.Equal(t, int64(1), labelIDs[0]) | |||
assert.Equal(t, int64(2), labelIDs[1]) | |||
assert.NoError(t, err) | |||
} | |||
func TestGetLabelInRepoByID(t *testing.T) { | |||
assert.NoError(t, PrepareTestDatabase()) | |||
label, err := GetLabelInRepoByID(1, 1) |
@@ -43,6 +43,10 @@ func ListIssues(ctx *context.APIContext) { | |||
// 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 | |||
@@ -71,20 +75,30 @@ func ListIssues(ctx *context.APIContext) { | |||
keyword = "" | |||
} | |||
var issueIDs []int64 | |||
var labelIDs []int64 | |||
var err error | |||
if len(keyword) > 0 { | |||
issueIDs, err = indexer.SearchIssuesByKeyword(ctx.Repo.Repository.ID, keyword) | |||
} | |||
if splitted := strings.Split(ctx.Query("labels"), ","); len(splitted) > 0 { | |||
labelIDs, err = models.GetLabelIDsInRepoByNames(ctx.Repo.Repository.ID, 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 { | |||
if len(keyword) == 0 || len(issueIDs) > 0 || len(labelIDs) > 0 { | |||
issues, err = models.Issues(&models.IssuesOptions{ | |||
RepoIDs: []int64{ctx.Repo.Repository.ID}, | |||
Page: ctx.QueryInt("page"), | |||
PageSize: setting.UI.IssuePagingNum, | |||
IsClosed: isClosed, | |||
IssueIDs: issueIDs, | |||
LabelIDs: labelIDs, | |||
}) | |||
} | |||
@@ -2059,6 +2059,12 @@ | |||
"name": "state", | |||
"in": "query" | |||
}, | |||
{ | |||
"type": "string", | |||
"description": "comma separated list of labels. Fetch only issues that have any of this labels. Non existent labels are discarded", | |||
"name": "labels", | |||
"in": "query" | |||
}, | |||
{ | |||
"type": "integer", | |||
"description": "page number of requested issues", |