Skip to content

Commit

Permalink
Merge 8ed027b into d55a2c9
Browse files Browse the repository at this point in the history
  • Loading branch information
nao1215 authored Feb 23, 2023
2 parents d55a2c9 + 8ed027b commit dc7f526
Show file tree
Hide file tree
Showing 14 changed files with 434 additions and 4 deletions.
14 changes: 10 additions & 4 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,17 @@ linters:
- varcheck
- asciicheck
- bodyclose
- cyclop
#- cyclop
- dogsled
- dupl
- durationcheck
- errorlint
- exhaustive
- exhaustivestruct
#- exhaustivestruct
- exportloopref
- forcetypeassert
- funlen
- gci
# - funlen
# - gci
- gochecknoglobals
- gochecknoinits
- goconst
Expand All @@ -55,3 +55,9 @@ linters:
- unparam
- wastedassign
- whitespace
linters-settings:
tagliatelle:
case:
use-field-name: true
rules:
json: snake
Empty file added cmd/.gitkeep
Empty file.
Empty file added config/.gitkeep
Empty file.
25 changes: 25 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Package config get setting from environment variable or configuration file.
package config

// Config represents configuration information for the leadtime CLI command.
// For example, include GitHub API access information.
type Config struct {
// GitHubAccessToken is access token for GitHub API.
GitHubAccessToken string
}

// Argument represents the argument for leadtime CLI startup.
type Argument struct {
// GitHubOwner is GitHun owner name(e.g. nao1215)
GitHubOwner string
// GitHubRepository is GitHub repository name(e.g. leadtime)
GitHubRepository string
}

// NewArgument initialize Argument struct.
func NewArgument(owner, repo string) *Argument {
return &Argument{
GitHubOwner: owner,
GitHubRepository: repo,
}
}
25 changes: 25 additions & 0 deletions config/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Package config get setting from environment variable or configuration file.
package config

import (
"testing"

"github.com/google/go-cmp/cmp"
)

func TestNewArgument(t *testing.T) {
t.Parallel()
t.Run("new argument", func(t *testing.T) {
t.Parallel()

want := &Argument{
GitHubOwner: "nao1215",
GitHubRepository: "leadtime",
}

got := NewArgument(want.GitHubOwner, want.GitHubRepository)
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("mismatch (-want +got):\n%s", diff)
}
})
}
22 changes: 22 additions & 0 deletions domain/model/github.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Package model is domain model and business logic.
package model

// Repository represents GitHub repository information
type Repository struct {
// ID is repository id
ID *int64 `json:"id,omitempty"`
// Owner is repository owner
Owner *User `json:"owner,omitempty"`
// Name is repository name
Name *string `json:"name,omitempty"`
// FullName is repository full name
FullName *string `json:"full_name,omitempty"`
// Description is repository description
Description *string `json:"description,omitempty"`
}

// User represents a GitHub user.
type User struct {
// Name is user name.
Name *string `json:"name,omitempty"`
}
Empty file added domain/repository/.gitkeep
Empty file.
Empty file added domain/service/.gitkeep
Empty file.
15 changes: 15 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
module github.com/nao1215/leadtime

go 1.20

require (
github.com/google/go-cmp v0.5.9
github.com/google/go-github/v50 v50.0.0
golang.org/x/oauth2 v0.5.0
)

require (
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/go-querystring v1.1.0 // indirect
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect
golang.org/x/net v0.6.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.28.0 // indirect
)
31 changes: 31 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
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.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/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.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-github/v50 v50.0.0 h1:gdO1AeuSZZK4iYWwVbjni7zg8PIQhp7QfmPunr016Jk=
github.com/google/go-github/v50 v50.0.0/go.mod h1:Ev4Tre8QoKiolvbpOSG3FIi4Mlon3S2Nt9W5JYqKiwA=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ=
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.6.0 h1:L4ZwwTvKW9gr0ZMS1yrHD9GZhIuVjOBBnaKH+SPQK0Q=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s=
golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
16 changes: 16 additions & 0 deletions infrastructure/github/error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package github

import "fmt"

// APIError is error for GitHub API.
type APIError struct {
// StatusCode is HTTP status code from GitHub.
StatusCode int
// Message is error message
Message string
}

// Error return string that represents a GitHub API error
func (e *APIError) Error() string {
return fmt.Sprintf("GitHub API error: status code %d, message: %s", e.StatusCode, e.Message)
}
43 changes: 43 additions & 0 deletions infrastructure/github/error_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package github

import (
"net/http"
"testing"
)

func TestAPIError_Error(t *testing.T) {
t.Parallel()

type fields struct {
StatusCode int
Message string
}
tests := []struct {
name string
fields fields
want string
}{
{
name: "Get 401 error",
fields: fields{
StatusCode: http.StatusUnauthorized,
Message: "unauthorized",
},
want: "GitHub API error: status code 401, message: unauthorized",
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()

e := &APIError{
StatusCode: tt.fields.StatusCode,
Message: tt.fields.Message,
}
if got := e.Error(); got != tt.want {
t.Errorf("APIError.Error() = %v, want %v", got, tt.want)
}
})
}
}
59 changes: 59 additions & 0 deletions infrastructure/github/github.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Package github is http client for GitHub API.
// This package is wrapper for google/go-github package.
package github

import (
"context"
"fmt"

"github.com/google/go-github/v50/github"
"github.com/nao1215/leadtime/domain/model"
"golang.org/x/oauth2"
)

// Client is http client for GitHub API.
type Client struct {
// client is http client
client *github.Client
}

// NewClient return http client for GitHub API.
func NewClient(token string) *Client {
tokenSource := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: token},
)
client := oauth2.NewClient(context.Background(), tokenSource)

return &Client{client: github.NewClient(client)}
}

// ListRepositories return List the repositories for a user.
func (c *Client) ListRepositories(ctx context.Context) ([]*model.Repository, error) {
repos, resp, err := c.client.Repositories.List(ctx, "", nil)
if resp != nil {
defer func() error {
if err := resp.Body.Close(); err != nil {
return fmt.Errorf("failed to close response body: %w", err)
}

return nil
}()
}
if err != nil {
return nil, &APIError{StatusCode: resp.StatusCode, Message: "failed to gey repository list"}
}

repoList := make([]*model.Repository, 0)
for _, v := range repos {
repo := &model.Repository{
ID: v.ID,
Owner: &model.User{Name: v.Owner.Name},
Name: v.Name,
FullName: v.FullName,
Description: v.Description,
}
repoList = append(repoList, repo)
}

return repoList, nil
}
Loading

0 comments on commit dc7f526

Please sign in to comment.