Skip to content

Commit

Permalink
version v0.2.0 implemented
Browse files Browse the repository at this point in the history
  • Loading branch information
GaMoCh committed Aug 25, 2021
1 parent 3ea0b3b commit 059b3be
Show file tree
Hide file tree
Showing 9 changed files with 172 additions and 35 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
.idea/
.vscode/
*.csv
10 changes: 10 additions & 0 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,13 @@ builds:
- linux
- darwin
- windows

- id: lab01s02
main: ./cmd/lab01s02
binary: bin/lab01s02
env:
- CGO_ENABLED=0
goos:
- linux
- darwin
- windows
90 changes: 81 additions & 9 deletions cmd/lab01s02/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@ package main

import (
"context"
"encoding/json"
"fmt"
"math"
"os"
"path/filepath"
"time"

"github.com/gamoch/popular_repos/internal/pkg/configuration"
"github.com/gamoch/popular_repos/pkg/graphql"
"github.com/gamoch/popular_repos/pkg/graphql/providers/github"
"github.com/gamoch/popular_repos/pkg/logs"

"github.com/cheggaaa/pb/v3"
"github.com/gocarina/gocsv"
)

const query = `query PopularRepos($cursor: String) {
Expand All @@ -23,7 +29,7 @@ const query = `query PopularRepos($cursor: String) {
stargazerCount
createdAt
updatedAt
pullRequests(states: MERGED) {
mergedPullRequests: pullRequests(states: MERGED) {
totalCount
}
releases {
Expand All @@ -32,7 +38,7 @@ const query = `query PopularRepos($cursor: String) {
primaryLanguage {
name
}
openIssues: issues(states: OPEN) {
issues {
totalCount
}
closedIssues: issues(states: CLOSED) {
Expand All @@ -50,16 +56,82 @@ func main() {
githubClient := github.NewClient(config.Token)
req := graphql.NewRequest(query)

graphQLData := new(GraphQLData)
if err := githubClient.Run(ctx, req, graphQLData); err != nil {
var nodes []GraphQLNode
var cursor *string

barTemplate := `Getting repositories... {{counters . }}`
bar := pb.ProgressBarTemplate(barTemplate).Start(10)

for i := 0; i < 10; i++ {
req.SetVariable("cursor", cursor)
bar.Increment()

graphQLData := new(GraphQLData)
if err := githubClient.Run(ctx, req, graphQLData); err != nil {
logs.Error.Fatal(err)
}

for _, node := range graphQLData.Search.Nodes {
nodes = append(nodes, node)
}

if !graphQLData.Search.PageInfo.HasNextPage {
break
}

cursor = &graphQLData.Search.PageInfo.EndCursor
}
bar.Finish()

var repositories []Repository
for _, node := range nodes {
repositories = append(repositories, graphQLNodeToRepository(node))
}

if err := writeRepositoriesToCSV(config, repositories); err != nil {
logs.Error.Fatal(err)
}
}

func graphQLNodeToRepository(node GraphQLNode) Repository {
percentageClosedIssues := 1.0
if node.Issues.TotalCount != 0 {
percentageClosedIssues = float64(node.ClosedIssues.TotalCount) / float64(node.Issues.TotalCount)
percentageClosedIssues = math.Round(percentageClosedIssues*100) / 100
}

return Repository{
NameWithOwner: node.NameWithOwner,
StargazerCount: node.StargazerCount,
Age: RepositoryTime{time.Since(node.CreatedAt).Truncate(time.Second)},
TimeUntilLastUpdate: RepositoryTime{time.Since(node.UpdatedAt).Truncate(time.Second)},
TotalAcceptedPullRequests: node.MergedPullRequests.TotalCount,
TotalReleases: node.Releases.TotalCount,
PrimaryLanguage: node.PrimaryLanguage.Name,
PercentageClosedIssues: percentageClosedIssues,
}
}

func writeRepositoriesToCSV(config *configuration.Config, repositories []Repository) error {
filePath := "repositories.csv"
if config.File != "" {
filePath = config.File

if err := os.MkdirAll(filepath.Dir(filePath), os.ModePerm); err != nil {
return err
}
}

graphqlJSON, err := json.MarshalIndent(graphQLData, "", " ")
file, err := os.Create(filePath)
if err != nil {
logs.Error.Fatal(err)
return err
}

graphqlJSON = append(graphqlJSON, '\n')
os.Stdout.Write(graphqlJSON)
if err = gocsv.MarshalFile(&repositories, file); err != nil {
return err
}

fmt.Println("Repositories saved at " + file.Name())

return nil
}
68 changes: 46 additions & 22 deletions cmd/lab01s02/structures.go
Original file line number Diff line number Diff line change
@@ -1,33 +1,57 @@
package main

import "time"
import (
"time"
)

type GraphQLData struct {
Search struct {
PageInfo struct {
HasNextPage bool `json:"hasNextPage"`
EndCursor string `json:"endCursor"`
} `json:"pageInfo"`
Nodes []struct {
NameWithOwner string `json:"nameWithOwner"`
StargazerCount int `json:"stargazerCount"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
PullRequests struct {
TotalCount int `json:"totalCount"`
} `json:"pullRequests"`
Releases struct {
TotalCount int `json:"totalCount"`
} `json:"releases"`
PrimaryLanguage *struct {
Name string `json:"name"`
} `json:"primaryLanguage"`
OpenIssues struct {
TotalCount int `json:"totalCount"`
} `json:"openIssues"`
ClosedIssues struct {
TotalCount int `json:"totalCount"`
} `json:"closedIssues"`
} `json:"nodes"`
Nodes []GraphQLNode `json:"nodes"`
} `json:"search"`
}

type GraphQLNode struct {
NameWithOwner string `json:"nameWithOwner"`
StargazerCount int `json:"stargazerCount"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
MergedPullRequests struct {
TotalCount int `json:"totalCount"`
} `json:"mergedPullRequests"`
Releases struct {
TotalCount int `json:"totalCount"`
} `json:"releases"`
PrimaryLanguage struct {
Name string `json:"name"`
} `json:"primaryLanguage"`
Issues struct {
TotalCount int `json:"totalCount"`
} `json:"issues"`
ClosedIssues struct {
TotalCount int `json:"totalCount"`
} `json:"closedIssues"`
}

type Repository struct {
NameWithOwner string `csv:"nameWithOwner"`
StargazerCount int `csv:"stargazerCount"`
Age RepositoryTime `csv:"age"`
TimeUntilLastUpdate RepositoryTime `csv:"timeUntilLastUpdate"`
TotalAcceptedPullRequests int `csv:"totalAcceptedPullRequests"`
TotalReleases int `csv:"totalReleases"`
PrimaryLanguage string `csv:"primaryLanguage"`
PercentageClosedIssues float64 `csv:"percentageClosedIssues"`
}

type RepositoryTime struct {
time.Duration
}

func (t *RepositoryTime) UnmarshalCSV(value string) (err error) {
t.Duration, err = time.ParseDuration(value)
return err
}
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
module github.com/gamoch/popular_repos

go 1.16

require (
github.com/cheggaaa/pb/v3 v3.0.8
github.com/gocarina/gocsv v0.0.0-20210516172204-ca9e8a8ddea8
)
21 changes: 21 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM=
github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA=
github.com/cheggaaa/pb/v3 v3.0.8 h1:bC8oemdChbke2FHIIGy9mn4DPJ2caZYQnfbRqwmdCoA=
github.com/cheggaaa/pb/v3 v3.0.8/go.mod h1:UICbiLec/XO6Hw6k+BHEtHeQFzzBH4i2/qk/ow1EJTA=
github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg=
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
github.com/gocarina/gocsv v0.0.0-20210516172204-ca9e8a8ddea8 h1:hp1oqdzmv37vPLYFGjuM/RmUgUMfD9vQfMszc54l55Y=
github.com/gocarina/gocsv v0.0.0-20210516172204-ca9e8a8ddea8/go.mod h1:5YoVOkjYAQumqlV356Hj3xeYh4BdZuLE0/nRkf2NKkI=
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-runewidth v0.0.12 h1:Y41i/hVW3Pgwr8gV+J23B9YEY0zxjptBuCWEaxmAOow=
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 h1:F5Gozwx4I1xtr/sr/8CFbb57iKi3297KFs0QDbGN60A=
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
9 changes: 6 additions & 3 deletions internal/pkg/configuration/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,18 @@ import (
"os"
)

type config struct {
type Config struct {
Token string
File string
}

func Get() *config {
func Get() *Config {
token := flag.String("token", os.Getenv("GITHUB_TOKEN"), "GitHub Token (env: GITHUB_TOKEN)")
file := flag.String("file", os.Getenv("CSV_FILE"), "CSV File Location (env: CSV_FILE)")
flag.Parse()

return &config{
return &Config{
Token: *token,
File: *file,
}
}
2 changes: 1 addition & 1 deletion pkg/graphql/providers/github/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func NewClient(token string, options ...graphql.ClientOption) *client {

func (c *client) Run(ctx context.Context, req *graphql.Request, res interface{}) error {
if req != nil {
req.Header.Add("Authorization", "bearer "+c.token)
req.Header.Set("Authorization", "bearer "+c.token)
}

err := c.client.Run(ctx, req, res)
Expand Down
1 change: 1 addition & 0 deletions pkg/graphql/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ func NewRequest(query string, options ...RequestOption) *Request {
func WithHTTPHeader(httpHeader http.Header) RequestOption {
return func(request *Request) {
for key, values := range httpHeader {
request.Header.Del(key)
for _, value := range values {
request.Header.Add(key, value)
}
Expand Down

0 comments on commit 059b3be

Please sign in to comment.