github.com/shohhei1126/hugo@v0.42.2-0.20180623210752-3d5928889ad7/releaser/github.go (about)

     1  package releaser
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"net/http"
     8  	"os"
     9  	"strings"
    10  )
    11  
    12  var (
    13  	gitHubCommitsAPI      = "https://api.github.com/repos/gohugoio/REPO/commits/%s"
    14  	gitHubRepoAPI         = "https://api.github.com/repos/gohugoio/REPO"
    15  	gitHubContributorsAPI = "https://api.github.com/repos/gohugoio/REPO/contributors"
    16  )
    17  
    18  type gitHubAPI struct {
    19  	commitsAPITemplate      string
    20  	repoAPI                 string
    21  	contributorsAPITemplate string
    22  }
    23  
    24  func newGitHubAPI(repo string) *gitHubAPI {
    25  	return &gitHubAPI{
    26  		commitsAPITemplate:      strings.Replace(gitHubCommitsAPI, "REPO", repo, -1),
    27  		repoAPI:                 strings.Replace(gitHubRepoAPI, "REPO", repo, -1),
    28  		contributorsAPITemplate: strings.Replace(gitHubContributorsAPI, "REPO", repo, -1),
    29  	}
    30  }
    31  
    32  type gitHubCommit struct {
    33  	Author  gitHubAuthor `json:"author"`
    34  	HtmlURL string       `json:"html_url"`
    35  }
    36  
    37  type gitHubAuthor struct {
    38  	ID        int    `json:"id"`
    39  	Login     string `json:"login"`
    40  	HtmlURL   string `json:"html_url"`
    41  	AvatarURL string `json:"avatar_url"`
    42  }
    43  
    44  type gitHubRepo struct {
    45  	ID           int    `json:"id"`
    46  	Name         string `json:"name"`
    47  	Description  string `json:"description"`
    48  	HtmlURL      string `json:"html_url"`
    49  	Stars        int    `json:"stargazers_count"`
    50  	Contributors []gitHubContributor
    51  }
    52  
    53  type gitHubContributor struct {
    54  	ID            int    `json:"id"`
    55  	Login         string `json:"login"`
    56  	HtmlURL       string `json:"html_url"`
    57  	Contributions int    `json:"contributions"`
    58  }
    59  
    60  func (g *gitHubAPI) fetchCommit(ref string) (gitHubCommit, error) {
    61  	var commit gitHubCommit
    62  
    63  	u := fmt.Sprintf(g.commitsAPITemplate, ref)
    64  
    65  	req, err := http.NewRequest("GET", u, nil)
    66  	if err != nil {
    67  		return commit, err
    68  	}
    69  
    70  	err = doGitHubRequest(req, &commit)
    71  
    72  	return commit, err
    73  }
    74  
    75  func (g *gitHubAPI) fetchRepo() (gitHubRepo, error) {
    76  	var repo gitHubRepo
    77  
    78  	req, err := http.NewRequest("GET", g.repoAPI, nil)
    79  	if err != nil {
    80  		return repo, err
    81  	}
    82  
    83  	err = doGitHubRequest(req, &repo)
    84  	if err != nil {
    85  		return repo, err
    86  	}
    87  
    88  	var contributors []gitHubContributor
    89  	page := 0
    90  	for {
    91  		page++
    92  		var currPage []gitHubContributor
    93  		url := fmt.Sprintf(g.contributorsAPITemplate+"?page=%d", page)
    94  
    95  		req, err = http.NewRequest("GET", url, nil)
    96  		if err != nil {
    97  			return repo, err
    98  		}
    99  
   100  		err = doGitHubRequest(req, &currPage)
   101  		if err != nil {
   102  			return repo, err
   103  		}
   104  		if len(currPage) == 0 {
   105  			break
   106  		}
   107  
   108  		contributors = append(contributors, currPage...)
   109  
   110  	}
   111  
   112  	repo.Contributors = contributors
   113  
   114  	return repo, err
   115  
   116  }
   117  
   118  func doGitHubRequest(req *http.Request, v interface{}) error {
   119  	addGitHubToken(req)
   120  
   121  	resp, err := http.DefaultClient.Do(req)
   122  	if err != nil {
   123  		return err
   124  	}
   125  	defer resp.Body.Close()
   126  
   127  	if isError(resp) {
   128  		b, _ := ioutil.ReadAll(resp.Body)
   129  		return fmt.Errorf("GitHub lookup failed: %s", string(b))
   130  	}
   131  
   132  	return json.NewDecoder(resp.Body).Decode(v)
   133  }
   134  
   135  func isError(resp *http.Response) bool {
   136  	return resp.StatusCode < 200 || resp.StatusCode > 299
   137  }
   138  
   139  func addGitHubToken(req *http.Request) {
   140  	gitHubToken := os.Getenv("GITHUB_TOKEN")
   141  	if gitHubToken != "" {
   142  		req.Header.Add("Authorization", "token "+gitHubToken)
   143  	}
   144  }