-
-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Refactors API client into hand rolled sdk in api/ directory
Signed-off-by: John McBride <[email protected]>
- Loading branch information
Showing
17 changed files
with
591 additions
and
172 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package api | ||
|
||
import ( | ||
"net/http" | ||
|
||
"github.com/open-sauced/pizza-cli/api/services/contributors" | ||
"github.com/open-sauced/pizza-cli/api/services/histogram" | ||
"github.com/open-sauced/pizza-cli/api/services/repository" | ||
) | ||
|
||
type Client struct { | ||
RepositoryService *repository.Service | ||
ContributorService *contributors.Service | ||
HistogramService *histogram.Service | ||
|
||
// The configured http client for making API requests | ||
httpClient *http.Client | ||
|
||
// The API endpoint to use when making requests | ||
// Example: https://api.opensauced.pizza | ||
endpoint string | ||
} | ||
|
||
func NewClient(endpoint string) *Client { | ||
client := Client{ | ||
httpClient: &http.Client{}, | ||
endpoint: endpoint, | ||
} | ||
|
||
repositoryService := repository.Service{ | ||
Endpoint: client.endpoint, | ||
} | ||
|
||
contributorService := contributors.Service{ | ||
Endpoint: client.endpoint, | ||
} | ||
|
||
histogramService := histogram.Service{ | ||
Endpoint: client.endpoint, | ||
} | ||
|
||
client.RepositoryService = &repositoryService | ||
client.ContributorService = &contributorService | ||
client.HistogramService = &histogramService | ||
|
||
return &client | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
package contributors | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"net/http" | ||
"net/url" | ||
"strings" | ||
) | ||
|
||
type Service struct { | ||
Endpoint string | ||
} | ||
|
||
func (s *Service) NewPullRequestContributors(repos []string, rangeVal int) (*ContribResponse, *http.Response, error) { | ||
baseURL := fmt.Sprintf("%s/v2/contributors/insights/new", s.Endpoint) | ||
|
||
// Create URL with query parameters | ||
u, err := url.Parse(baseURL) | ||
if err != nil { | ||
return nil, nil, fmt.Errorf("error parsing URL: %v", err) | ||
} | ||
|
||
q := u.Query() | ||
q.Set("range", fmt.Sprintf("%d", rangeVal)) | ||
q.Set("repos", strings.Join(repos, ",")) | ||
u.RawQuery = q.Encode() | ||
|
||
resp, err := http.Get(u.String()) | ||
if err != nil { | ||
return nil, resp, fmt.Errorf("error making request: %v", err) | ||
} | ||
defer resp.Body.Close() | ||
|
||
if resp.StatusCode != http.StatusOK { | ||
return nil, resp, fmt.Errorf("API request failed with status code: %d", resp.StatusCode) | ||
} | ||
|
||
var newContributorsResponse ContribResponse | ||
if err := json.NewDecoder(resp.Body).Decode(&newContributorsResponse); err != nil { | ||
return nil, resp, fmt.Errorf("error decoding response: %v", err) | ||
} | ||
|
||
return &newContributorsResponse, resp, nil | ||
} | ||
|
||
func (s *Service) RecentPullRequestContributors(repos []string, rangeVal int) (*ContribResponse, *http.Response, error) { | ||
baseURL := fmt.Sprintf("%s/v2/contributors/insights/recent", s.Endpoint) | ||
|
||
// Create URL with query parameters | ||
u, err := url.Parse(baseURL) | ||
if err != nil { | ||
return nil, nil, fmt.Errorf("error parsing URL: %v", err) | ||
} | ||
|
||
q := u.Query() | ||
q.Set("range", fmt.Sprintf("%d", rangeVal)) | ||
q.Set("repos", strings.Join(repos, ",")) | ||
u.RawQuery = q.Encode() | ||
|
||
resp, err := http.Get(u.String()) | ||
if err != nil { | ||
return nil, resp, fmt.Errorf("error making request: %v", err) | ||
} | ||
defer resp.Body.Close() | ||
|
||
if resp.StatusCode != http.StatusOK { | ||
return nil, resp, fmt.Errorf("API request failed with status code: %d", resp.StatusCode) | ||
} | ||
|
||
var recentContributorsResponse ContribResponse | ||
if err := json.NewDecoder(resp.Body).Decode(&recentContributorsResponse); err != nil { | ||
return nil, resp, fmt.Errorf("error decoding response: %v", err) | ||
} | ||
|
||
return &recentContributorsResponse, resp, nil | ||
} | ||
|
||
func (s *Service) AlumniPullRequestContributors(repos []string, rangeVal int) (*ContribResponse, *http.Response, error) { | ||
baseURL := fmt.Sprintf("%s/v2/contributors/insights/alumni", s.Endpoint) | ||
|
||
// Create URL with query parameters | ||
u, err := url.Parse(baseURL) | ||
if err != nil { | ||
return nil, nil, fmt.Errorf("error parsing URL: %v", err) | ||
} | ||
|
||
q := u.Query() | ||
q.Set("range", fmt.Sprintf("%d", rangeVal)) | ||
q.Set("repos", strings.Join(repos, ",")) | ||
u.RawQuery = q.Encode() | ||
|
||
resp, err := http.Get(u.String()) | ||
if err != nil { | ||
return nil, resp, fmt.Errorf("error making request: %v", err) | ||
} | ||
defer resp.Body.Close() | ||
|
||
if resp.StatusCode != http.StatusOK { | ||
return nil, resp, fmt.Errorf("API request failed with status code: %d", resp.StatusCode) | ||
} | ||
|
||
var alumniContributorsResponse ContribResponse | ||
if err := json.NewDecoder(resp.Body).Decode(&alumniContributorsResponse); err != nil { | ||
return nil, resp, fmt.Errorf("error decoding response: %v", err) | ||
} | ||
|
||
return &alumniContributorsResponse, resp, nil | ||
} | ||
|
||
func (s *Service) RepeatPullRequestContributors(repos []string, rangeVal int) (*ContribResponse, *http.Response, error) { | ||
baseURL := fmt.Sprintf("%s/v2/contributors/insights/repeat", s.Endpoint) | ||
|
||
// Create URL with query parameters | ||
u, err := url.Parse(baseURL) | ||
if err != nil { | ||
return nil, nil, fmt.Errorf("error parsing URL: %v", err) | ||
} | ||
|
||
q := u.Query() | ||
q.Set("range", fmt.Sprintf("%d", rangeVal)) | ||
q.Set("repos", strings.Join(repos, ",")) | ||
u.RawQuery = q.Encode() | ||
|
||
resp, err := http.Get(u.String()) | ||
if err != nil { | ||
return nil, resp, fmt.Errorf("error making request: %v", err) | ||
} | ||
defer resp.Body.Close() | ||
|
||
if resp.StatusCode != http.StatusOK { | ||
return nil, resp, fmt.Errorf("API request failed with status code: %d", resp.StatusCode) | ||
} | ||
|
||
var repeatContributorsResponse ContribResponse | ||
if err := json.NewDecoder(resp.Body).Decode(&repeatContributorsResponse); err != nil { | ||
return nil, resp, fmt.Errorf("error decoding response: %v", err) | ||
} | ||
|
||
return &repeatContributorsResponse, resp, nil | ||
} | ||
|
||
func (s *Service) SearchPullRequestContributors(repoIDs []int, rangeVal int) (*ContribResponse, *http.Response, error) { | ||
baseURL := fmt.Sprintf("%s/v2/contributors/search", s.Endpoint) | ||
|
||
// Create URL with query parameters | ||
u, err := url.Parse(baseURL) | ||
if err != nil { | ||
return nil, nil, fmt.Errorf("error parsing URL: %v", err) | ||
} | ||
|
||
q := u.Query() | ||
q.Set("range", fmt.Sprintf("%d", rangeVal)) | ||
q.Set("repoIds", strings.Join(strings.Fields(fmt.Sprint(repoIDs)), ",")) | ||
u.RawQuery = q.Encode() | ||
|
||
resp, err := http.Get(u.String()) | ||
if err != nil { | ||
return nil, resp, fmt.Errorf("error making request: %v", err) | ||
} | ||
defer resp.Body.Close() | ||
|
||
if resp.StatusCode != http.StatusOK { | ||
return nil, resp, fmt.Errorf("API request failed with status code: %d", resp.StatusCode) | ||
} | ||
|
||
var searchContributorsResponse ContribResponse | ||
if err := json.NewDecoder(resp.Body).Decode(&searchContributorsResponse); err != nil { | ||
return nil, resp, fmt.Errorf("error decoding response: %v", err) | ||
} | ||
|
||
return &searchContributorsResponse, resp, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package contributors | ||
|
||
import ( | ||
"time" | ||
|
||
"github.com/open-sauced/pizza-cli/api/services" | ||
) | ||
|
||
type DbContributor struct { | ||
AuthorLogin string `json:"author_login"` | ||
UserID int `json:"user_id"` | ||
UpdatedAt time.Time `json:"updated_at"` | ||
} | ||
|
||
type ContribResponse struct { | ||
Data []DbContributor `json:"data"` | ||
Meta services.MetaData `json:"meta"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package histogram | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"net/http" | ||
"net/url" | ||
) | ||
|
||
type Service struct { | ||
Endpoint string | ||
} | ||
|
||
func (s *Service) PrsHistogram(repo string, rangeVal int) ([]PrHistogramData, *http.Response, error) { | ||
baseURL := fmt.Sprintf("%s/v2/histogram/pull-requests", s.Endpoint) | ||
|
||
// Create URL with query parameters | ||
u, err := url.Parse(baseURL) | ||
if err != nil { | ||
return nil, nil, fmt.Errorf("error parsing URL: %v", err) | ||
} | ||
|
||
q := u.Query() | ||
q.Set("range", fmt.Sprintf("%d", rangeVal)) | ||
q.Set("repo", repo) | ||
u.RawQuery = q.Encode() | ||
|
||
resp, err := http.Get(u.String()) | ||
if err != nil { | ||
return nil, resp, fmt.Errorf("error making request: %v", err) | ||
} | ||
defer resp.Body.Close() | ||
|
||
if resp.StatusCode != http.StatusOK { | ||
return nil, resp, fmt.Errorf("API request failed with status code: %d", resp.StatusCode) | ||
} | ||
|
||
var prHistogramData []PrHistogramData | ||
if err := json.NewDecoder(resp.Body).Decode(&prHistogramData); err != nil { | ||
return nil, resp, fmt.Errorf("error decoding response: %v", err) | ||
} | ||
|
||
return prHistogramData, resp, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package histogram | ||
|
||
import "time" | ||
|
||
type PrHistogramData struct { | ||
Bucket time.Time `json:"bucket"` | ||
PrCount int `json:"pr_count"` | ||
AcceptedPrs int `json:"accepted_prs"` | ||
OpenPrs int `json:"open_prs"` | ||
ClosedPrs int `json:"closed_prs"` | ||
DraftPrs int `json:"draft_prs"` | ||
ActivePrs int `json:"active_prs"` | ||
SpamPrs int `json:"spam_prs"` | ||
PRVelocity int `json:"pr_velocity"` | ||
CollaboratorAssociatedPrs int `json:"collaborator_associated_prs"` | ||
ContributorAssociatedPrs int `json:"contributor_associated_prs"` | ||
MemberAssociatedPrs int `json:"member_associated_prs"` | ||
NonAssociatedPrs int `json:"non_associated_prs"` | ||
OwnerAssociatedPrs int `json:"owner_associated_prs"` | ||
CommentsOnPrs int `json:"comments_on_prs"` | ||
ReviewCommentsOnPrs int `json:"review_comments_on_prs"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package repository | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"io" | ||
"net/http" | ||
"net/url" | ||
) | ||
|
||
type Service struct { | ||
Endpoint string | ||
} | ||
|
||
func (rs *Service) FindOneByOwnerAndRepo(owner string, repo string) (*DbRepository, *http.Response, error) { | ||
url := fmt.Sprintf("%s/v2/repos/%s/%s", rs.Endpoint, owner, repo) | ||
|
||
resp, err := http.Get(url) | ||
if err != nil { | ||
return nil, resp, fmt.Errorf("error making request: %v", err) | ||
} | ||
defer resp.Body.Close() | ||
|
||
if resp.StatusCode != http.StatusOK { | ||
return nil, resp, fmt.Errorf("API request failed with status code: %d", resp.StatusCode) | ||
} | ||
|
||
var repository DbRepository | ||
if err := json.NewDecoder(resp.Body).Decode(&repository); err != nil { | ||
return nil, resp, fmt.Errorf("error decoding response: %v", err) | ||
} | ||
|
||
return &repository, resp, nil | ||
} | ||
|
||
func (rs *Service) FindContributorsByOwnerAndRepo(owner string, repo string, rangeVal int) (*ContributorsResponse, *http.Response, error) { | ||
baseURL := fmt.Sprintf("%s/v2/repos/%s/%s", rs.Endpoint, owner, repo) | ||
|
||
// Create URL with query parameters | ||
u, err := url.Parse(baseURL) | ||
if err != nil { | ||
return nil, nil, fmt.Errorf("error parsing URL: %v", err) | ||
} | ||
|
||
q := u.Query() | ||
q.Set("range", fmt.Sprintf("%d", rangeVal)) | ||
u.RawQuery = q.Encode() | ||
|
||
resp, err := http.Get(u.String()) | ||
if err != nil { | ||
return nil, resp, err | ||
} | ||
defer resp.Body.Close() | ||
|
||
body, err := io.ReadAll(resp.Body) | ||
if err != nil { | ||
return nil, resp, err | ||
} | ||
|
||
var contributorsResp ContributorsResponse | ||
err = json.Unmarshal(body, &contributorsResp) | ||
if err != nil { | ||
return nil, resp, err | ||
} | ||
|
||
return &contributorsResp, resp, nil | ||
} |
Oops, something went wrong.