initial commit for querying github

This commit is contained in:
Christian Griggs 2024-08-20 18:49:34 -04:00
parent 9a45ed0e3c
commit 63ed95b780
3 changed files with 194 additions and 2 deletions

5
go.mod
View File

@ -5,6 +5,8 @@ go 1.21
require ( require (
github.com/PuerkitoBio/goquery v1.8.1 github.com/PuerkitoBio/goquery v1.8.1
github.com/avelino/slugify v0.0.0-20180501145920-855f152bd774 github.com/avelino/slugify v0.0.0-20180501145920-855f152bd774
github.com/google/go-github/v63 v63.0.0
github.com/kr/pretty v0.3.1
github.com/otiai10/copy v1.14.0 github.com/otiai10/copy v1.14.0
github.com/yuin/goldmark v1.6.0 github.com/yuin/goldmark v1.6.0
golang.org/x/oauth2 v0.15.0 golang.org/x/oauth2 v0.15.0
@ -13,6 +15,9 @@ require (
require ( require (
github.com/andybalholm/cascadia v1.3.1 // indirect github.com/andybalholm/cascadia v1.3.1 // indirect
github.com/golang/protobuf v1.5.3 // indirect github.com/golang/protobuf v1.5.3 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/rogpeppe/go-internal v1.9.0 // indirect
golang.org/x/net v0.23.0 // indirect golang.org/x/net v0.23.0 // indirect
golang.org/x/sync v0.3.0 // indirect golang.org/x/sync v0.3.0 // indirect
golang.org/x/sys v0.18.0 // indirect golang.org/x/sys v0.18.0 // indirect

17
go.sum
View File

@ -4,17 +4,30 @@ github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x0
github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA= github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA=
github.com/avelino/slugify v0.0.0-20180501145920-855f152bd774 h1:HrMVYtly2IVqg9EBooHsakQ256ueojP7QuG32K71X/U= github.com/avelino/slugify v0.0.0-20180501145920-855f152bd774 h1:HrMVYtly2IVqg9EBooHsakQ256ueojP7QuG32K71X/U=
github.com/avelino/slugify v0.0.0-20180501145920-855f152bd774/go.mod h1:5wi5YYOpfuAKwL5XLFYopbgIl/v7NZxaJpa/4X6yFKE= github.com/avelino/slugify v0.0.0-20180501145920-855f152bd774/go.mod h1:5wi5YYOpfuAKwL5XLFYopbgIl/v7NZxaJpa/4X6yFKE=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-github/v63 v63.0.0 h1:13xwK/wk9alSokujB9lJkuzdmQuVn2QCPeck76wR3nE=
github.com/google/go-github/v63 v63.0.0/go.mod h1:IqbcrgUmIcEaioWrGYei/09o+ge5vhffGOcxrO0AfmA=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/otiai10/copy v1.14.0 h1:dCI/t1iTdYGtkvCuBG2BgR6KZa83PTclw4U5n2wAllU= github.com/otiai10/copy v1.14.0 h1:dCI/t1iTdYGtkvCuBG2BgR6KZa83PTclw4U5n2wAllU=
github.com/otiai10/copy v1.14.0/go.mod h1:ECfuL02W+/FkTWZWgQqXPWZgW9oeKCSQ5qVfSc4qc4w= github.com/otiai10/copy v1.14.0/go.mod h1:ECfuL02W+/FkTWZWgQqXPWZgW9oeKCSQ5qVfSc4qc4w=
github.com/otiai10/mint v1.5.1 h1:XaPLeE+9vGbuyEHem1JNk3bYc7KKqyI/na0/mLd/Kks= github.com/otiai10/mint v1.5.1 h1:XaPLeE+9vGbuyEHem1JNk3bYc7KKqyI/na0/mLd/Kks=
github.com/otiai10/mint v1.5.1/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM= github.com/otiai10/mint v1.5.1/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yuin/goldmark v1.6.0 h1:boZcn2GTjpsynOsC0iJHnBWa4Bi0qzfJjthwauItG68= github.com/yuin/goldmark v1.6.0 h1:boZcn2GTjpsynOsC0iJHnBWa4Bi0qzfJjthwauItG68=
github.com/yuin/goldmark v1.6.0/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.6.0/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=

View File

@ -0,0 +1,174 @@
package main
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"regexp"
"testing"
"time"
"github.com/kr/pretty"
)
const gqlQuery = `
query {
repository(owner:"%s", name:"%s") {
name
openIssues: issues(states: OPEN) {
totalCount
}
lastUpdatedIssue: issues(first: 1, orderBy: {field: UPDATED_AT, direction: DESC}) {
edges {
node {
updatedAt
}
}
}
defaultBranchRef {
target {
... on Commit {
committedDate
}
}
}
forks {
totalCount
}
stargazers {
totalCount
}
}
}
`
var authToken = os.ExpandEnv("$GITHUB_PAT")
func repoTimeSinceLastUpdated(repo GithubRepoResponse) time.Duration {
return time.Since(repo.Data.Repository.DefaultBranchRef.Target.CommittedDate)
}
type awesomeRepo struct {
RepoName string
RepoOrganization string
ReadmeLine int
}
type GithubRepoResponse struct {
Data struct {
Repository struct {
Name string `json:"name"`
OpenIssues struct {
TotalCount int `json:"totalCount"`
} `json:"openIssues"`
LastUpdatedIssue struct {
Edges []struct {
Node struct {
UpdatedAt time.Time `json:"updatedAt"`
} `json:"node"`
} `json:"edges"`
} `json:"lastUpdatedIssue"`
DefaultBranchRef struct {
Target struct {
CommittedDate time.Time `json:"committedDate"`
} `json:"target"`
} `json:"defaultBranchRef"`
Forks struct {
TotalCount int `json:"totalCount"`
} `json:"forks"`
Stargazers struct {
TotalCount int `json:"totalCount"`
} `json:"stargazers"`
} `json:"repository"`
} `json:"data"`
}
type repoStats struct {
TimeLastUpdated time.Duration
Stars int
Forks int
}
func checkHealth(repo awesomeRepo) (*repoStats, error) {
requestBody := struct {
Query string `json:"query"`
}{
fmt.Sprintf(gqlQuery, repo.RepoOrganization, repo.RepoName),
}
body, err := json.Marshal(requestBody)
if err != nil {
return nil, err
}
req, err := http.NewRequestWithContext(context.Background(), "POST", "https://api.github.com/graphql", bytes.NewReader(body))
if err != nil {
return nil, err
}
req.Header.Add("Authorization", "Bearer "+authToken)
res, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
resbody, err := io.ReadAll(res.Body)
if err != nil {
return nil, err
}
var response GithubRepoResponse
if err := json.Unmarshal(resbody, &response); err != nil {
return nil, err
}
timeSinceUpdated := repoTimeSinceLastUpdated(response)
health := repoStats{
TimeLastUpdated: timeSinceUpdated,
}
return &health, nil
}
func TestCleanUpLibs(t *testing.T) {
bytes, err := os.ReadFile("README.md")
if err != nil {
t.Error(err)
}
r := regexp.MustCompile(`\((https.*)\)`)
// only support github right now
for _, result := range r.FindAllSubmatch(bytes, -1) {
org, p, err := extractGithubRepo(result[1])
if err != nil {
continue
}
fmt.Println("org", org, "package", p, "err", err)
a := awesomeRepo{
RepoOrganization: org,
RepoName: p,
}
health, err := checkHealth(a)
if err != nil {
t.Error(err)
}
pretty.Println(health)
}
}
var getRepo = regexp.MustCompile(`https://github.com/(.*)/(.*)[\)]?`)
func extractGithubRepo(b []byte) (string, string, error) {
results := getRepo.FindSubmatch(b)
if len(results) == 0 {
return "", "", fmt.Errorf("no match found for %s", string(b))
}
return string(results[1]), string(results[2]), nil
}