Add label names as filter in issue search api (#5946)
This commit is contained in:
		
							parent
							
								
									f21ae12abb
								
							
						
					
					
						commit
						024871ade6
					
				
					 4 changed files with 59 additions and 2 deletions
				
			
		|  | @ -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", | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue