github.com/ungtb10d/cli/v2@v2.0.0-20221110210412-98537dd9d6a1/pkg/search/result.go (about)

     1  package search
     2  
     3  import (
     4  	"reflect"
     5  	"strings"
     6  	"time"
     7  )
     8  
     9  var RepositoryFields = []string{
    10  	"createdAt",
    11  	"defaultBranch",
    12  	"description",
    13  	"forksCount",
    14  	"fullName",
    15  	"hasDownloads",
    16  	"hasIssues",
    17  	"hasPages",
    18  	"hasProjects",
    19  	"hasWiki",
    20  	"homepage",
    21  	"id",
    22  	"isArchived",
    23  	"isDisabled",
    24  	"isFork",
    25  	"isPrivate",
    26  	"language",
    27  	"license",
    28  	"name",
    29  	"openIssuesCount",
    30  	"owner",
    31  	"pushedAt",
    32  	"size",
    33  	"stargazersCount",
    34  	"updatedAt",
    35  	"url",
    36  	"visibility",
    37  	"watchersCount",
    38  }
    39  
    40  var IssueFields = []string{
    41  	"assignees",
    42  	"author",
    43  	"authorAssociation",
    44  	"body",
    45  	"closedAt",
    46  	"commentsCount",
    47  	"createdAt",
    48  	"id",
    49  	"isLocked",
    50  	"isPullRequest",
    51  	"labels",
    52  	"number",
    53  	"repository",
    54  	"state",
    55  	"title",
    56  	"updatedAt",
    57  	"url",
    58  }
    59  
    60  type RepositoriesResult struct {
    61  	IncompleteResults bool         `json:"incomplete_results"`
    62  	Items             []Repository `json:"items"`
    63  	Total             int          `json:"total_count"`
    64  }
    65  
    66  type IssuesResult struct {
    67  	IncompleteResults bool    `json:"incomplete_results"`
    68  	Items             []Issue `json:"items"`
    69  	Total             int     `json:"total_count"`
    70  }
    71  
    72  type Repository struct {
    73  	CreatedAt       time.Time `json:"created_at"`
    74  	DefaultBranch   string    `json:"default_branch"`
    75  	Description     string    `json:"description"`
    76  	ForksCount      int       `json:"forks_count"`
    77  	FullName        string    `json:"full_name"`
    78  	HasDownloads    bool      `json:"has_downloads"`
    79  	HasIssues       bool      `json:"has_issues"`
    80  	HasPages        bool      `json:"has_pages"`
    81  	HasProjects     bool      `json:"has_projects"`
    82  	HasWiki         bool      `json:"has_wiki"`
    83  	Homepage        string    `json:"homepage"`
    84  	ID              string    `json:"node_id"`
    85  	IsArchived      bool      `json:"archived"`
    86  	IsDisabled      bool      `json:"disabled"`
    87  	IsFork          bool      `json:"fork"`
    88  	IsPrivate       bool      `json:"private"`
    89  	Language        string    `json:"language"`
    90  	License         License   `json:"license"`
    91  	MasterBranch    string    `json:"master_branch"`
    92  	Name            string    `json:"name"`
    93  	OpenIssuesCount int       `json:"open_issues_count"`
    94  	Owner           User      `json:"owner"`
    95  	PushedAt        time.Time `json:"pushed_at"`
    96  	Size            int       `json:"size"`
    97  	StargazersCount int       `json:"stargazers_count"`
    98  	URL             string    `json:"html_url"`
    99  	UpdatedAt       time.Time `json:"updated_at"`
   100  	Visibility      string    `json:"visibility"`
   101  	WatchersCount   int       `json:"watchers_count"`
   102  }
   103  
   104  type License struct {
   105  	Key  string `json:"key"`
   106  	Name string `json:"name"`
   107  	URL  string `json:"url"`
   108  }
   109  
   110  type User struct {
   111  	GravatarID string `json:"gravatar_id"`
   112  	ID         string `json:"node_id"`
   113  	Login      string `json:"login"`
   114  	SiteAdmin  bool   `json:"site_admin"`
   115  	Type       string `json:"type"`
   116  	URL        string `json:"html_url"`
   117  }
   118  
   119  type Issue struct {
   120  	Assignees         []User      `json:"assignees"`
   121  	Author            User        `json:"user"`
   122  	AuthorAssociation string      `json:"author_association"`
   123  	Body              string      `json:"body"`
   124  	ClosedAt          time.Time   `json:"closed_at"`
   125  	CommentsCount     int         `json:"comments"`
   126  	CreatedAt         time.Time   `json:"created_at"`
   127  	ID                string      `json:"node_id"`
   128  	Labels            []Label     `json:"labels"`
   129  	IsLocked          bool        `json:"locked"`
   130  	Number            int         `json:"number"`
   131  	PullRequest       PullRequest `json:"pull_request"`
   132  	RepositoryURL     string      `json:"repository_url"`
   133  	// StateInternal should not be used directly. Use State() instead.
   134  	StateInternal string    `json:"state"`
   135  	StateReason   string    `json:"state_reason"`
   136  	Title         string    `json:"title"`
   137  	URL           string    `json:"html_url"`
   138  	UpdatedAt     time.Time `json:"updated_at"`
   139  }
   140  
   141  type PullRequest struct {
   142  	URL      string    `json:"html_url"`
   143  	MergedAt time.Time `json:"merged_at"`
   144  }
   145  
   146  // the state of an issue or a pull request,
   147  // may be either open or closed.
   148  // for a pull request, the "merged" state is
   149  // inferred from a value for merged_at and
   150  // which we take return instead of the "closed" state.
   151  func (issue Issue) State() string {
   152  	if !issue.PullRequest.MergedAt.IsZero() {
   153  		return "merged"
   154  	}
   155  	return issue.StateInternal
   156  }
   157  
   158  type Label struct {
   159  	Color       string `json:"color"`
   160  	Description string `json:"description"`
   161  	ID          string `json:"node_id"`
   162  	Name        string `json:"name"`
   163  }
   164  
   165  func (repo Repository) ExportData(fields []string) map[string]interface{} {
   166  	v := reflect.ValueOf(repo)
   167  	data := map[string]interface{}{}
   168  	for _, f := range fields {
   169  		switch f {
   170  		case "license":
   171  			data[f] = map[string]interface{}{
   172  				"key":  repo.License.Key,
   173  				"name": repo.License.Name,
   174  				"url":  repo.License.URL,
   175  			}
   176  		case "owner":
   177  			data[f] = map[string]interface{}{
   178  				"id":    repo.Owner.ID,
   179  				"login": repo.Owner.Login,
   180  				"type":  repo.Owner.Type,
   181  				"url":   repo.Owner.URL,
   182  			}
   183  		default:
   184  			sf := fieldByName(v, f)
   185  			data[f] = sf.Interface()
   186  		}
   187  	}
   188  	return data
   189  }
   190  
   191  func (issue Issue) IsPullRequest() bool {
   192  	return issue.PullRequest.URL != ""
   193  }
   194  
   195  func (issue Issue) ExportData(fields []string) map[string]interface{} {
   196  	v := reflect.ValueOf(issue)
   197  	data := map[string]interface{}{}
   198  	for _, f := range fields {
   199  		switch f {
   200  		case "assignees":
   201  			assignees := make([]interface{}, 0, len(issue.Assignees))
   202  			for _, assignee := range issue.Assignees {
   203  				assignees = append(assignees, map[string]interface{}{
   204  					"id":    assignee.ID,
   205  					"login": assignee.Login,
   206  					"type":  assignee.Type,
   207  				})
   208  			}
   209  			data[f] = assignees
   210  		case "author":
   211  			data[f] = map[string]interface{}{
   212  				"id":    issue.Author.ID,
   213  				"login": issue.Author.Login,
   214  				"type":  issue.Author.Type,
   215  			}
   216  		case "isPullRequest":
   217  			data[f] = issue.IsPullRequest()
   218  		case "labels":
   219  			labels := make([]interface{}, 0, len(issue.Labels))
   220  			for _, label := range issue.Labels {
   221  				labels = append(labels, map[string]interface{}{
   222  					"color":       label.Color,
   223  					"description": label.Description,
   224  					"id":          label.ID,
   225  					"name":        label.Name,
   226  				})
   227  			}
   228  			data[f] = labels
   229  		case "repository":
   230  			comp := strings.Split(issue.RepositoryURL, "/")
   231  			name := comp[len(comp)-1]
   232  			nameWithOwner := strings.Join(comp[len(comp)-2:], "/")
   233  			data[f] = map[string]interface{}{
   234  				"name":          name,
   235  				"nameWithOwner": nameWithOwner,
   236  			}
   237  		case "state":
   238  			data[f] = issue.State()
   239  		default:
   240  			sf := fieldByName(v, f)
   241  			data[f] = sf.Interface()
   242  		}
   243  	}
   244  	return data
   245  }
   246  
   247  func fieldByName(v reflect.Value, field string) reflect.Value {
   248  	return v.FieldByNameFunc(func(s string) bool {
   249  		return strings.EqualFold(field, s)
   250  	})
   251  }