You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
kratos/cmd/kratos/internal/change/get.go

211 lines
4.6 KiB

package change
import (
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"os"
"regexp"
"strings"
"time"
)
type ReleaseInfo struct {
Author struct {
Login string `json:"login"`
} `json:"author"`
PublishedAt string `json:"published_at"`
Body string `json:"body"`
HTMLURL string `json:"html_url"`
}
type CommitInfo struct {
Commit struct {
Message string `json:"message"`
} `json:"commit"`
}
type ErrorInfo struct {
Message string
}
type GithubAPI struct {
Owner string
Repo string
Token string
}
// GetReleaseInfo for getting kratos release info.
func (g *GithubAPI) GetReleaseInfo(version string) ReleaseInfo {
api := fmt.Sprintf("https://api.github.com/repos/%s/%s/releases/latest", g.Owner, g.Repo)
if version != "latest" {
api = fmt.Sprintf("https://api.github.com/repos/%s/%s/releases/tags/%s", g.Owner, g.Repo, version)
}
resp, code := requestGithubAPI(api, "GET", nil, g.Token)
if code != http.StatusOK {
printGithubErrorInfo(resp)
}
releaseInfo := ReleaseInfo{}
err := json.Unmarshal(resp, &releaseInfo)
if err != nil {
fatal(err)
}
return releaseInfo
}
// GetCommitsInfo for getting kratos commits info.
func (g *GithubAPI) GetCommitsInfo() []CommitInfo {
info := g.GetReleaseInfo("latest")
page := 1
var list []CommitInfo
for {
url := fmt.Sprintf("https://api.github.com/repos/%s/%s/commits?pre_page=100&page=%d&since=%s", g.Owner, g.Repo, page, info.PublishedAt)
resp, code := requestGithubAPI(url, "GET", nil, g.Token)
if code != http.StatusOK {
printGithubErrorInfo(resp)
}
var res []CommitInfo
err := json.Unmarshal(resp, &res)
if err != nil {
fatal(err)
}
list = append(list, res...)
if len(res) < http.StatusContinue {
break
}
page++
}
return list
}
func printGithubErrorInfo(body []byte) {
errorInfo := &ErrorInfo{}
err := json.Unmarshal(body, errorInfo)
if err != nil {
fatal(err)
}
fatal(errors.New(errorInfo.Message))
}
func requestGithubAPI(url string, method string, body io.Reader, token string) ([]byte, int) {
cli := &http.Client{Timeout: 60 * time.Second}
request, err := http.NewRequest(method, url, body)
if err != nil {
fatal(err)
}
if token != "" {
request.Header.Add("Authorization", token)
}
resp, err := cli.Do(request)
if err != nil {
fatal(err)
}
defer resp.Body.Close()
resBody, err := io.ReadAll(resp.Body)
if err != nil {
fatal(err)
}
return resBody, resp.StatusCode
}
func ParseCommitsInfo(info []CommitInfo) string {
group := map[string][]string{
"fix": {},
"feat": {},
"deps": {},
"break": {},
"chore": {},
"other": {},
}
for _, commitInfo := range info {
msg := commitInfo.Commit.Message
index := strings.Index(fmt.Sprintf("%q", msg), `\n`)
if index != -1 {
msg = msg[:index-1]
}
prefix := []string{"fix", "feat", "deps", "break", "chore"}
var matched bool
for _, v := range prefix {
msg = strings.TrimPrefix(msg, " ")
if strings.HasPrefix(msg, v) {
group[v] = append(group[v], msg)
matched = true
}
}
if !matched {
group["other"] = append(group["other"], msg)
}
}
md := make(map[string]string)
for key, value := range group {
var text string
switch key {
case "break":
text = "### Breaking Changes\n"
case "deps":
text = "### Dependencies\n"
case "feat":
text = "### New Features\n"
case "fix":
text = "### Bug Fixes\n"
case "chore":
text = "### Chores\n"
case "other":
text = "### Others\n"
}
if len(value) > 0 {
md[key] += text
for _, value := range value {
md[key] += fmt.Sprintf("- %s\n", value)
}
}
}
return fmt.Sprint(md["break"], md["deps"], md["feat"], md["fix"], md["chore"], md["other"])
}
func ParseReleaseInfo(info ReleaseInfo) string {
reg := regexp.MustCompile(`(?m)^\s*$[\r\n]*|[\r\n]+\s+\z|<[\S\s]+?>`)
body := reg.ReplaceAll([]byte(info.Body), []byte(""))
if string(body) == "" {
body = []byte("no release info")
}
splitters := "--------------------------------------------"
return fmt.Sprintf(
"Author: %s\nDate: %s\nUrl: %s\n\n%s\n\n%s\n\n%s\n",
info.Author.Login,
info.PublishedAt,
info.HTMLURL,
splitters,
body,
splitters,
)
}
func ParseGithubURL(url string) (owner string, repo string) {
var start int
start = strings.Index(url, "//")
if start == -1 {
start = strings.Index(url, ":") + 1
} else {
start += 2
}
end := strings.LastIndex(url, "/")
gitIndex := strings.LastIndex(url, ".git")
if gitIndex == -1 {
repo = url[strings.LastIndex(url, "/")+1:]
} else {
repo = url[strings.LastIndex(url, "/")+1 : gitIndex]
}
tmp := url[start:end]
owner = tmp[strings.Index(tmp, "/")+1:]
return
}
func fatal(err error) {
fmt.Fprintf(os.Stderr, "\033[31mERROR: %s\033[m\n", err)
os.Exit(1)
}