github.com/cli/cli@v1.14.1-0.20210902173923-1af6a669e342/pkg/githubsearch/query.go (about)

     1  package githubsearch
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  )
     7  
     8  type EntityType string
     9  type State string
    10  type RepoVisibility string
    11  type SortField string
    12  type SortDirection int
    13  
    14  const (
    15  	Asc SortDirection = iota
    16  	Desc
    17  
    18  	UpdatedAt SortField = "updated"
    19  	CreatedAt SortField = "created"
    20  
    21  	Issue       EntityType = "issue"
    22  	PullRequest EntityType = "pr"
    23  
    24  	Open   State = "open"
    25  	Closed State = "closed"
    26  	Merged State = "merged"
    27  
    28  	Public  RepoVisibility = "public"
    29  	Private RepoVisibility = "private"
    30  )
    31  
    32  func NewQuery() *Query {
    33  	return &Query{}
    34  }
    35  
    36  type Query struct {
    37  	repo  string
    38  	owner string
    39  	sort  string
    40  	query string
    41  
    42  	entity     string
    43  	state      string
    44  	baseBranch string
    45  	headBranch string
    46  	labels     []string
    47  	assignee   string
    48  	author     string
    49  	mentions   string
    50  	milestone  string
    51  
    52  	language   string
    53  	topic      string
    54  	forkState  string
    55  	visibility string
    56  	isArchived *bool
    57  }
    58  
    59  func (q *Query) InRepository(nameWithOwner string) {
    60  	q.repo = nameWithOwner
    61  }
    62  
    63  func (q *Query) OwnedBy(owner string) {
    64  	q.owner = owner
    65  }
    66  
    67  func (q *Query) SortBy(field SortField, direction SortDirection) {
    68  	var dir string
    69  	switch direction {
    70  	case Asc:
    71  		dir = "asc"
    72  	case Desc:
    73  		dir = "desc"
    74  	}
    75  	q.sort = fmt.Sprintf("%s-%s", field, dir)
    76  }
    77  
    78  func (q *Query) AddQuery(query string) {
    79  	q.query = query
    80  }
    81  
    82  func (q *Query) SetType(t EntityType) {
    83  	q.entity = string(t)
    84  }
    85  
    86  func (q *Query) SetState(s State) {
    87  	q.state = string(s)
    88  }
    89  
    90  func (q *Query) SetBaseBranch(name string) {
    91  	q.baseBranch = name
    92  }
    93  
    94  func (q *Query) SetHeadBranch(name string) {
    95  	q.headBranch = name
    96  }
    97  
    98  func (q *Query) AssignedTo(user string) {
    99  	q.assignee = user
   100  }
   101  
   102  func (q *Query) AuthoredBy(user string) {
   103  	q.author = user
   104  }
   105  
   106  func (q *Query) Mentions(handle string) {
   107  	q.mentions = handle
   108  }
   109  
   110  func (q *Query) InMilestone(title string) {
   111  	q.milestone = title
   112  }
   113  
   114  func (q *Query) AddLabel(name string) {
   115  	q.labels = append(q.labels, name)
   116  }
   117  
   118  func (q *Query) SetLanguage(name string) {
   119  	q.language = name
   120  }
   121  
   122  func (q *Query) SetTopic(name string) {
   123  	q.topic = name
   124  }
   125  
   126  func (q *Query) SetVisibility(visibility RepoVisibility) {
   127  	q.visibility = string(visibility)
   128  }
   129  
   130  func (q *Query) OnlyForks() {
   131  	q.forkState = "only"
   132  }
   133  
   134  func (q *Query) IncludeForks(include bool) {
   135  	q.forkState = fmt.Sprintf("%v", include)
   136  }
   137  
   138  func (q *Query) SetArchived(isArchived bool) {
   139  	q.isArchived = &isArchived
   140  }
   141  
   142  func (q *Query) String() string {
   143  	var qs string
   144  
   145  	// context
   146  	if q.repo != "" {
   147  		qs += fmt.Sprintf("repo:%s ", q.repo)
   148  	} else if q.owner != "" {
   149  		qs += fmt.Sprintf("user:%s ", q.owner)
   150  	}
   151  
   152  	// type
   153  	if q.entity != "" {
   154  		qs += fmt.Sprintf("is:%s ", q.entity)
   155  	}
   156  	if q.state != "" {
   157  		qs += fmt.Sprintf("is:%s ", q.state)
   158  	}
   159  
   160  	// repositories
   161  	if q.visibility != "" {
   162  		qs += fmt.Sprintf("is:%s ", q.visibility)
   163  	}
   164  	if q.language != "" {
   165  		qs += fmt.Sprintf("language:%s ", quote(q.language))
   166  	}
   167  	if q.topic != "" {
   168  		qs += fmt.Sprintf("topic:%s ", quote(q.topic))
   169  	}
   170  	if q.forkState != "" {
   171  		qs += fmt.Sprintf("fork:%s ", q.forkState)
   172  	}
   173  	if q.isArchived != nil {
   174  		qs += fmt.Sprintf("archived:%v ", *q.isArchived)
   175  	}
   176  
   177  	// issues
   178  	if q.assignee != "" {
   179  		qs += fmt.Sprintf("assignee:%s ", q.assignee)
   180  	}
   181  	for _, label := range q.labels {
   182  		qs += fmt.Sprintf("label:%s ", quote(label))
   183  	}
   184  	if q.author != "" {
   185  		qs += fmt.Sprintf("author:%s ", q.author)
   186  	}
   187  	if q.mentions != "" {
   188  		qs += fmt.Sprintf("mentions:%s ", q.mentions)
   189  	}
   190  	if q.milestone != "" {
   191  		qs += fmt.Sprintf("milestone:%s ", quote(q.milestone))
   192  	}
   193  
   194  	// pull requests
   195  	if q.baseBranch != "" {
   196  		qs += fmt.Sprintf("base:%s ", quote(q.baseBranch))
   197  	}
   198  	if q.headBranch != "" {
   199  		qs += fmt.Sprintf("head:%s ", quote(q.headBranch))
   200  	}
   201  
   202  	if q.sort != "" {
   203  		qs += fmt.Sprintf("sort:%s ", q.sort)
   204  	}
   205  	return strings.TrimRight(qs+q.query, " ")
   206  }
   207  
   208  func quote(v string) string {
   209  	if strings.ContainsAny(v, " \"\t\r\n") {
   210  		return fmt.Sprintf("%q", v)
   211  	}
   212  	return v
   213  }