Initial commit
This commit is contained in:
305
pr/pr.go
Normal file
305
pr/pr.go
Normal file
@@ -0,0 +1,305 @@
|
||||
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)
|
||||
|
||||
}
|
37
pr/types.go
Normal file
37
pr/types.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package pr
|
||||
|
||||
type pr struct {
|
||||
ID int16 `json:"id"`
|
||||
URL string `json:"url"`
|
||||
Number int16 `json:"number"`
|
||||
Title string `json:"title"`
|
||||
Base struct {
|
||||
Ref string `json:"ref"`
|
||||
}
|
||||
Head struct {
|
||||
Ref string `json:"ref"`
|
||||
}
|
||||
Created string `json:"created_at"`
|
||||
User struct {
|
||||
Username string `json:"username,omitempty"`
|
||||
FullName string `json:"full_name,omitempty"`
|
||||
}
|
||||
}
|
||||
|
||||
type metadata struct {
|
||||
Number string `json:"number"`
|
||||
Title string `json:"title"`
|
||||
Base string `json:"base"`
|
||||
Head string `json:"head"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
CreatedBy string `json:"createdBy"`
|
||||
}
|
||||
|
||||
type getStdout struct {
|
||||
Version stdoutVersion
|
||||
Metadata metadata
|
||||
}
|
||||
|
||||
type stdoutVersion struct {
|
||||
Ref string `json:"ref"`
|
||||
}
|
Reference in New Issue
Block a user