306 lines
5.9 KiB
Go
306 lines
5.9 KiB
Go
package pr
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"net/url"
|
|
"os"
|
|
"path"
|
|
"sort"
|
|
"strconv"
|
|
"strings"
|
|
"text/tabwriter"
|
|
|
|
"github.com/avanier/gitea-resource/util"
|
|
)
|
|
|
|
// List returns a slice of PRs
|
|
func List(stdinPayload util.STDINPayload) {
|
|
var (
|
|
err error
|
|
stdoutVersions []stdoutVersion
|
|
)
|
|
|
|
if stdinPayload.Source.SkipSSLVerification {
|
|
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
|
|
}
|
|
|
|
client := &http.Client{}
|
|
|
|
req, err := http.NewRequest("GET", composeAllPrURL(stdinPayload.Source), nil)
|
|
|
|
if !stdinPayload.Source.Insecure && len(stdinPayload.Source.AccessToken) > 0 {
|
|
req.Header.Add("Authorization", stdinPayload.Source.AccessToken)
|
|
}
|
|
|
|
response, err := client.Do(req)
|
|
util.CheckResponse(response)
|
|
|
|
/*
|
|
CAVEAT EMPTOR
|
|
|
|
This does not page. So, for some reason if you have more than 50 PRs addeed
|
|
since you last checked, or you run this for the first time, and you set version
|
|
to `every`, this will only show the 50 first. You can either change Gitea's
|
|
number of API items returned, or create a PR a pager here.
|
|
|
|
https://docs.gitea.io/en-us/api-usage/
|
|
*/
|
|
|
|
if err != nil {
|
|
util.HandleError(err)
|
|
}
|
|
|
|
data, _ := ioutil.ReadAll(response.Body)
|
|
|
|
prs := []pr{} // Slice of PRs
|
|
err = json.Unmarshal(data, &prs)
|
|
|
|
if err != nil {
|
|
util.HandleError(err)
|
|
}
|
|
|
|
fmt.Fprintf(os.Stderr, "prs returned: %d\n", len(prs))
|
|
fmt.Fprintf(os.Stderr, "minimum version: %s\n", stdinPayload.Version.Number)
|
|
|
|
prs = filterPRs(prs, stdinPayload.Version.Number)
|
|
prs = sortPRs(prs)
|
|
|
|
table := tabwriter.NewWriter(os.Stderr, 0, 0, 1, ' ', tabwriter.TabIndent)
|
|
header := []string{
|
|
"Number",
|
|
"Url",
|
|
"Title",
|
|
"Creator",
|
|
"Date Created",
|
|
"Base Ref",
|
|
"Head Ref",
|
|
}
|
|
|
|
if len(prs) > 0 {
|
|
fmt.Fprintln(table, strings.Join(header, "\t"))
|
|
} else {
|
|
fmt.Fprintln(os.Stderr, "no prs detected beyond the last known version")
|
|
}
|
|
|
|
for ind, onePr := range prs {
|
|
stdoutVersions = append(stdoutVersions, stdoutVersion{Ref: strconv.Itoa(int(onePr.Number))})
|
|
|
|
if ind == 0 {
|
|
fmt.Printf("\n")
|
|
}
|
|
|
|
lineElems := []string{
|
|
fmt.Sprint(onePr.Number),
|
|
onePr.URL,
|
|
onePr.Title,
|
|
extractUser(onePr),
|
|
onePr.Created,
|
|
onePr.Base.Ref,
|
|
onePr.Head.Ref,
|
|
}
|
|
|
|
fmt.Fprintln(table, strings.Join(lineElems, "\t"))
|
|
}
|
|
|
|
err = table.Flush()
|
|
|
|
if err != nil {
|
|
util.HandleError(err)
|
|
}
|
|
|
|
stdoutData, err := json.MarshalIndent(stdoutVersions, "", " ")
|
|
|
|
if err != nil {
|
|
util.HandleError(err)
|
|
}
|
|
|
|
fmt.Fprintln(os.Stdout, string(stdoutData))
|
|
}
|
|
|
|
func composeAllPrURL(sourceConfig util.SourceConfig) string {
|
|
urlString := &url.URL{}
|
|
|
|
if sourceConfig.Insecure {
|
|
urlString.Scheme = "http"
|
|
} else {
|
|
urlString.Scheme = "https"
|
|
}
|
|
|
|
urlString.Host = strings.Join([]string{
|
|
sourceConfig.Hostname,
|
|
sourceConfig.Port},
|
|
":",
|
|
)
|
|
|
|
urlPath := path.Join(
|
|
"api",
|
|
"v1",
|
|
"repos",
|
|
sourceConfig.Owner,
|
|
sourceConfig.Repo,
|
|
"pulls",
|
|
)
|
|
|
|
urlString.Path = urlPath
|
|
|
|
queryString := url.Values{}
|
|
queryString.Set("state", "open")
|
|
queryString.Set("sort", "oldest")
|
|
|
|
urlString.RawQuery = queryString.Encode()
|
|
|
|
return urlString.String()
|
|
}
|
|
|
|
func composeSinglePrURL(source util.STDINPayload) string {
|
|
urlString := &url.URL{}
|
|
|
|
if source.Source.Insecure {
|
|
urlString.Scheme = "http"
|
|
} else {
|
|
urlString.Scheme = "https"
|
|
}
|
|
|
|
urlString.Host = strings.Join([]string{
|
|
source.Source.Hostname,
|
|
source.Source.Port},
|
|
":",
|
|
)
|
|
|
|
urlPath := path.Join(
|
|
"api",
|
|
"v1",
|
|
"repos",
|
|
source.Source.Owner,
|
|
source.Source.Repo,
|
|
"pulls",
|
|
source.Version.Number,
|
|
)
|
|
|
|
urlString.Path = urlPath
|
|
|
|
return urlString.String()
|
|
}
|
|
|
|
func extractUser(onePr pr) string {
|
|
var user string
|
|
|
|
if onePr.User.FullName != "" {
|
|
user = onePr.User.FullName
|
|
} else {
|
|
user = onePr.User.Username
|
|
}
|
|
|
|
return user
|
|
}
|
|
|
|
func sortPRs(prs []pr) []pr {
|
|
sort.SliceStable(prs, func(leftInd, rightInd int) bool {
|
|
return prs[leftInd].Number < prs[rightInd].Number
|
|
})
|
|
|
|
return prs
|
|
}
|
|
|
|
func filterPRs(prs []pr, minVersStr string) []pr {
|
|
filteredPRs := []pr{}
|
|
|
|
minVer, err := strconv.ParseInt(minVersStr, 10, 64)
|
|
|
|
if err != nil {
|
|
util.HandleError(err)
|
|
}
|
|
|
|
for _, onePR := range prs {
|
|
if int64(onePR.Number) > minVer {
|
|
filteredPRs = append(filteredPRs, onePR)
|
|
}
|
|
}
|
|
|
|
return filteredPRs
|
|
}
|
|
|
|
// Get fetches the raw json of the PR object from the API and outputs it to a file
|
|
func Get(stdinPayload util.STDINPayload, dest string) {
|
|
var (
|
|
err error
|
|
thisPR pr
|
|
)
|
|
|
|
if stdinPayload.Source.SkipSSLVerification {
|
|
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
|
|
}
|
|
|
|
client := &http.Client{}
|
|
|
|
req, err := http.NewRequest("GET", composeSinglePrURL(stdinPayload), nil)
|
|
|
|
if err != nil {
|
|
util.HandleError(err)
|
|
}
|
|
|
|
if !stdinPayload.Source.Insecure && len(stdinPayload.Source.AccessToken) > 0 {
|
|
req.Header.Add("Authorization", stdinPayload.Source.AccessToken)
|
|
}
|
|
|
|
response, err := client.Do(req)
|
|
util.CheckResponse(response)
|
|
|
|
data, _ := ioutil.ReadAll(response.Body)
|
|
err = json.Unmarshal(data, &thisPR)
|
|
|
|
if err != nil {
|
|
util.HandleError(err)
|
|
}
|
|
|
|
metadataPayload := metadata{
|
|
Number: strconv.Itoa(int(thisPR.Number)),
|
|
Title: thisPR.Title,
|
|
Base: thisPR.Base.Ref,
|
|
Head: thisPR.Head.Ref,
|
|
CreatedAt: thisPR.Created,
|
|
CreatedBy: extractUser(thisPR),
|
|
}
|
|
|
|
stdoutPayload := getStdout{
|
|
Version: stdoutVersion{
|
|
Ref: strconv.Itoa(int(thisPR.Number)),
|
|
},
|
|
Metadata: metadataPayload,
|
|
}
|
|
|
|
stdoutData, err := json.MarshalIndent(stdoutPayload, "", " ")
|
|
fmt.Fprintln(os.Stdout, string(stdoutData))
|
|
|
|
rawDestFile := path.Join(
|
|
dest,
|
|
"pr.json",
|
|
)
|
|
|
|
metaDestFile := path.Join(
|
|
dest,
|
|
"metadata.json",
|
|
)
|
|
|
|
err = ioutil.WriteFile(rawDestFile, data, 0644)
|
|
|
|
if err != nil {
|
|
util.HandleError(err)
|
|
}
|
|
|
|
fmt.Fprintf(os.Stderr, "raw data written to %s\n", rawDestFile)
|
|
|
|
err = ioutil.WriteFile(metaDestFile, stdoutData, 0644)
|
|
|
|
if err != nil {
|
|
util.HandleError(err)
|
|
}
|
|
|
|
fmt.Fprintf(os.Stderr, "resource metadata written to %s\n", metaDestFile)
|
|
|
|
}
|