github.com/google/go-github/v65@v65.0.0/github/repos_stats.go (about)

     1  // Copyright 2014 The go-github AUTHORS. All rights reserved.
     2  //
     3  // Use of this source code is governed by a BSD-style
     4  // license that can be found in the LICENSE file.
     5  
     6  package github
     7  
     8  import (
     9  	"context"
    10  	"fmt"
    11  	"time"
    12  )
    13  
    14  // ContributorStats represents a contributor to a repository and their
    15  // weekly contributions to a given repo.
    16  type ContributorStats struct {
    17  	Author *Contributor   `json:"author,omitempty"`
    18  	Total  *int           `json:"total,omitempty"`
    19  	Weeks  []*WeeklyStats `json:"weeks,omitempty"`
    20  }
    21  
    22  func (c ContributorStats) String() string {
    23  	return Stringify(c)
    24  }
    25  
    26  // WeeklyStats represents the number of additions, deletions and commits
    27  // a Contributor made in a given week.
    28  type WeeklyStats struct {
    29  	Week      *Timestamp `json:"w,omitempty"`
    30  	Additions *int       `json:"a,omitempty"`
    31  	Deletions *int       `json:"d,omitempty"`
    32  	Commits   *int       `json:"c,omitempty"`
    33  }
    34  
    35  func (w WeeklyStats) String() string {
    36  	return Stringify(w)
    37  }
    38  
    39  // ListContributorsStats gets a repo's contributor list with additions,
    40  // deletions and commit counts.
    41  //
    42  // If this is the first time these statistics are requested for the given
    43  // repository, this method will return an *AcceptedError and a status code of
    44  // 202. This is because this is the status that GitHub returns to signify that
    45  // it is now computing the requested statistics. A follow up request, after a
    46  // delay of a second or so, should result in a successful request.
    47  //
    48  // GitHub API docs: https://docs.github.com/rest/metrics/statistics#get-all-contributor-commit-activity
    49  //
    50  //meta:operation GET /repos/{owner}/{repo}/stats/contributors
    51  func (s *RepositoriesService) ListContributorsStats(ctx context.Context, owner, repo string) ([]*ContributorStats, *Response, error) {
    52  	u := fmt.Sprintf("repos/%v/%v/stats/contributors", owner, repo)
    53  	req, err := s.client.NewRequest("GET", u, nil)
    54  	if err != nil {
    55  		return nil, nil, err
    56  	}
    57  
    58  	var contributorStats []*ContributorStats
    59  	resp, err := s.client.Do(ctx, req, &contributorStats)
    60  	if err != nil {
    61  		return nil, resp, err
    62  	}
    63  
    64  	return contributorStats, resp, nil
    65  }
    66  
    67  // WeeklyCommitActivity represents the weekly commit activity for a repository.
    68  // The days array is a group of commits per day, starting on Sunday.
    69  type WeeklyCommitActivity struct {
    70  	Days  []int      `json:"days,omitempty"`
    71  	Total *int       `json:"total,omitempty"`
    72  	Week  *Timestamp `json:"week,omitempty"`
    73  }
    74  
    75  func (w WeeklyCommitActivity) String() string {
    76  	return Stringify(w)
    77  }
    78  
    79  // ListCommitActivity returns the last year of commit activity
    80  // grouped by week. The days array is a group of commits per day,
    81  // starting on Sunday.
    82  //
    83  // If this is the first time these statistics are requested for the given
    84  // repository, this method will return an *AcceptedError and a status code of
    85  // 202. This is because this is the status that GitHub returns to signify that
    86  // it is now computing the requested statistics. A follow up request, after a
    87  // delay of a second or so, should result in a successful request.
    88  //
    89  // GitHub API docs: https://docs.github.com/rest/metrics/statistics#get-the-last-year-of-commit-activity
    90  //
    91  //meta:operation GET /repos/{owner}/{repo}/stats/commit_activity
    92  func (s *RepositoriesService) ListCommitActivity(ctx context.Context, owner, repo string) ([]*WeeklyCommitActivity, *Response, error) {
    93  	u := fmt.Sprintf("repos/%v/%v/stats/commit_activity", owner, repo)
    94  	req, err := s.client.NewRequest("GET", u, nil)
    95  	if err != nil {
    96  		return nil, nil, err
    97  	}
    98  
    99  	var weeklyCommitActivity []*WeeklyCommitActivity
   100  	resp, err := s.client.Do(ctx, req, &weeklyCommitActivity)
   101  	if err != nil {
   102  		return nil, resp, err
   103  	}
   104  
   105  	return weeklyCommitActivity, resp, nil
   106  }
   107  
   108  // ListCodeFrequency returns a weekly aggregate of the number of additions and
   109  // deletions pushed to a repository. Returned WeeklyStats will contain
   110  // additions and deletions, but not total commits.
   111  //
   112  // If this is the first time these statistics are requested for the given
   113  // repository, this method will return an *AcceptedError and a status code of
   114  // 202. This is because this is the status that GitHub returns to signify that
   115  // it is now computing the requested statistics. A follow up request, after a
   116  // delay of a second or so, should result in a successful request.
   117  //
   118  // GitHub API docs: https://docs.github.com/rest/metrics/statistics#get-the-weekly-commit-activity
   119  //
   120  //meta:operation GET /repos/{owner}/{repo}/stats/code_frequency
   121  func (s *RepositoriesService) ListCodeFrequency(ctx context.Context, owner, repo string) ([]*WeeklyStats, *Response, error) {
   122  	u := fmt.Sprintf("repos/%v/%v/stats/code_frequency", owner, repo)
   123  	req, err := s.client.NewRequest("GET", u, nil)
   124  	if err != nil {
   125  		return nil, nil, err
   126  	}
   127  
   128  	var weeks [][]int
   129  	resp, err := s.client.Do(ctx, req, &weeks)
   130  	if err != nil {
   131  		return nil, resp, err
   132  	}
   133  
   134  	// convert int slices into WeeklyStats
   135  	var stats []*WeeklyStats
   136  	for _, week := range weeks {
   137  		if len(week) != 3 {
   138  			continue
   139  		}
   140  		stat := &WeeklyStats{
   141  			Week:      &Timestamp{time.Unix(int64(week[0]), 0)},
   142  			Additions: Int(week[1]),
   143  			Deletions: Int(week[2]),
   144  		}
   145  		stats = append(stats, stat)
   146  	}
   147  
   148  	return stats, resp, nil
   149  }
   150  
   151  // RepositoryParticipation is the number of commits by everyone
   152  // who has contributed to the repository (including the owner)
   153  // as well as the number of commits by the owner themself.
   154  type RepositoryParticipation struct {
   155  	All   []int `json:"all,omitempty"`
   156  	Owner []int `json:"owner,omitempty"`
   157  }
   158  
   159  func (r RepositoryParticipation) String() string {
   160  	return Stringify(r)
   161  }
   162  
   163  // ListParticipation returns the total commit counts for the 'owner'
   164  // and total commit counts in 'all'. 'all' is everyone combined,
   165  // including the 'owner' in the last 52 weeks. If you’d like to get
   166  // the commit counts for non-owners, you can subtract 'all' from 'owner'.
   167  //
   168  // The array order is oldest week (index 0) to most recent week.
   169  //
   170  // If this is the first time these statistics are requested for the given
   171  // repository, this method will return an *AcceptedError and a status code of
   172  // 202. This is because this is the status that GitHub returns to signify that
   173  // it is now computing the requested statistics. A follow up request, after a
   174  // delay of a second or so, should result in a successful request.
   175  //
   176  // GitHub API docs: https://docs.github.com/rest/metrics/statistics#get-the-weekly-commit-count
   177  //
   178  //meta:operation GET /repos/{owner}/{repo}/stats/participation
   179  func (s *RepositoriesService) ListParticipation(ctx context.Context, owner, repo string) (*RepositoryParticipation, *Response, error) {
   180  	u := fmt.Sprintf("repos/%v/%v/stats/participation", owner, repo)
   181  	req, err := s.client.NewRequest("GET", u, nil)
   182  	if err != nil {
   183  		return nil, nil, err
   184  	}
   185  
   186  	participation := new(RepositoryParticipation)
   187  	resp, err := s.client.Do(ctx, req, participation)
   188  	if err != nil {
   189  		return nil, resp, err
   190  	}
   191  
   192  	return participation, resp, nil
   193  }
   194  
   195  // PunchCard represents the number of commits made during a given hour of a
   196  // day of the week.
   197  type PunchCard struct {
   198  	Day     *int // Day of the week (0-6: =Sunday - Saturday).
   199  	Hour    *int // Hour of day (0-23).
   200  	Commits *int // Number of commits.
   201  }
   202  
   203  // ListPunchCard returns the number of commits per hour in each day.
   204  //
   205  // If this is the first time these statistics are requested for the given
   206  // repository, this method will return an *AcceptedError and a status code of
   207  // 202. This is because this is the status that GitHub returns to signify that
   208  // it is now computing the requested statistics. A follow up request, after a
   209  // delay of a second or so, should result in a successful request.
   210  //
   211  // GitHub API docs: https://docs.github.com/rest/metrics/statistics#get-the-hourly-commit-count-for-each-day
   212  //
   213  //meta:operation GET /repos/{owner}/{repo}/stats/punch_card
   214  func (s *RepositoriesService) ListPunchCard(ctx context.Context, owner, repo string) ([]*PunchCard, *Response, error) {
   215  	u := fmt.Sprintf("repos/%v/%v/stats/punch_card", owner, repo)
   216  	req, err := s.client.NewRequest("GET", u, nil)
   217  	if err != nil {
   218  		return nil, nil, err
   219  	}
   220  
   221  	var results [][]int
   222  	resp, err := s.client.Do(ctx, req, &results)
   223  	if err != nil {
   224  		return nil, resp, err
   225  	}
   226  
   227  	// convert int slices into Punchcards
   228  	var cards []*PunchCard
   229  	for _, result := range results {
   230  		if len(result) != 3 {
   231  			continue
   232  		}
   233  		card := &PunchCard{
   234  			Day:     Int(result[0]),
   235  			Hour:    Int(result[1]),
   236  			Commits: Int(result[2]),
   237  		}
   238  		cards = append(cards, card)
   239  	}
   240  
   241  	return cards, resp, nil
   242  }