Skip to content

Commit

Permalink
Extract graphql HTTP request helper
Browse files Browse the repository at this point in the history
  • Loading branch information
chelmertz committed Dec 30, 2023
1 parent fa8b1cb commit 517624c
Showing 1 changed file with 21 additions and 53 deletions.
74 changes: 21 additions & 53 deletions internal/github/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,17 +137,15 @@ func checkExpiration(expiration string, logger *slog.Logger) {
}
}

// UsernameFromPat() will return the username for the given personal access
// token, to avoid having to provide the username explicitly.
func UsernameFromPat(token string, logger *slog.Logger) (string, error) {
func graphqlRequest(query, token string, logger *slog.Logger) ([]byte, error) {
payload := struct {
Query string `json:"query"`
}{
Query: `query { viewer { login } }`,
Query: query,
}
jsonBytes, err := json.Marshal(payload)
if err != nil {
return "", fmt.Errorf("could not marshal username json: %w", err)
return nil, fmt.Errorf("could not marshal graphql json: %w", err)
}

ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
Expand All @@ -158,13 +156,13 @@ func UsernameFromPat(token string, logger *slog.Logger) (string, error) {
request, err := http.NewRequestWithContext(ctx, "POST", "https://api.github.com/graphql", bytes.NewReader(jsonBytes))
request.Header.Add("Authorization", "bearer "+token)
if err != nil {
return "", fmt.Errorf("could not construct github username request: %w", err)
return nil, fmt.Errorf("could not construct github request: %w", err)
}

logger.Info("querying github api for username")
logger.Info("querying github api")
response, err := httpClient.Do(request)
if err != nil {
return "", fmt.Errorf("could not request github for username: %w", err)
return nil, fmt.Errorf("could not request github: %w", err)
}
defer response.Body.Close()

Expand All @@ -174,15 +172,25 @@ func UsernameFromPat(token string, logger *slog.Logger) (string, error) {

respBody, err := io.ReadAll(response.Body)
if err != nil {
return "", fmt.Errorf("could not read github username response: %w", err)
return nil, fmt.Errorf("could not read github username response: %w", err)
}

if response.StatusCode >= 400 {
logger.Warn("response", slog.Int("response_code", response.StatusCode), slog.String("body", string(respBody)))
if response.StatusCode < 500 {
return "", ErrClient
return nil, ErrClient
}
return "", ErrGithubServer
return nil, ErrGithubServer
}
return respBody, nil
}

// UsernameFromPat() will return the username for the given personal access
// token, to avoid having to provide the username explicitly.
func UsernameFromPat(token string, logger *slog.Logger) (string, error) {
respBody, err := graphqlRequest(`query { viewer { login } }`, token, logger)
if err != nil {
return "", fmt.Errorf("could not query github for username: %w", err)
}

var typedResponse struct {
Expand All @@ -201,49 +209,9 @@ func UsernameFromPat(token string, logger *slog.Logger) (string, error) {
}

func QueryGithub(token string, username string, logger *slog.Logger) ([]types.ViewPr, error) {
payload := struct {
Query string `json:"query"`
}{
Query: querySearchPrsInvolvingUser(username),
}
jsonBytes, err := json.Marshal(payload)
if err != nil {
return nil, fmt.Errorf("could not marshal pr query json: %w", err)
}

ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer cancel()

httpClient := &http.Client{}

request, err := http.NewRequestWithContext(ctx, "POST", "https://api.github.com/graphql", bytes.NewReader(jsonBytes))
request.Header.Add("Authorization", "bearer "+token)
if err != nil {
return nil, fmt.Errorf("could not construct github request: %w", err)
}

logger.Info("querying github api")
response, err := httpClient.Do(request)
respBody, err := graphqlRequest(querySearchPrsInvolvingUser(username), token, logger)
if err != nil {
return nil, fmt.Errorf("could not request github: %w", err)
}
defer response.Body.Close()

if expiration := response.Header.Get("Github-Authentication-Token-Expiration"); expiration != "" {
checkExpiration(expiration, logger)
}

respBody, err := io.ReadAll(response.Body)
if err != nil {
return nil, fmt.Errorf("could not read github response: %w", err)
}

if response.StatusCode >= 400 {
logger.Warn("response", slog.Int("response_code", response.StatusCode), slog.String("body", string(respBody)))
if response.StatusCode < 500 {
return nil, ErrClient
}
return nil, ErrGithubServer
return nil, fmt.Errorf("could not query github for PRs: %v", err)
}

typedResponse := querySearchPrsInvolvingMeGraphQl{}
Expand Down

0 comments on commit 517624c

Please sign in to comment.