databricks-cli/cmd/labs/github/github.go

67 lines
1.6 KiB
Go

package github
import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"strings"
"github.com/databricks/cli/libs/log"
)
const gitHubAPI = "https://api.github.com"
const gitHubUserContent = "https://raw.githubusercontent.com"
// Placeholders to use as unique keys in context.Context.
var apiOverride int
var userContentOverride int
func WithApiOverride(ctx context.Context, override string) context.Context {
return context.WithValue(ctx, &apiOverride, override)
}
func WithUserContentOverride(ctx context.Context, override string) context.Context {
return context.WithValue(ctx, &userContentOverride, override)
}
var ErrNotFound = errors.New("not found")
func getBytes(ctx context.Context, method, url string, body io.Reader) ([]byte, error) {
ao, ok := ctx.Value(&apiOverride).(string)
if ok {
url = strings.Replace(url, gitHubAPI, ao, 1)
}
uco, ok := ctx.Value(&userContentOverride).(string)
if ok {
url = strings.Replace(url, gitHubUserContent, uco, 1)
}
log.Tracef(ctx, "%s %s", method, url)
req, err := http.NewRequestWithContext(ctx, "GET", url, body)
if err != nil {
return nil, err
}
res, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
if res.StatusCode == 404 {
return nil, ErrNotFound
}
if res.StatusCode >= 400 {
return nil, fmt.Errorf("github request failed: %s", res.Status)
}
defer res.Body.Close()
return io.ReadAll(res.Body)
}
func httpGetAndUnmarshal(ctx context.Context, url string, response any) error {
raw, err := getBytes(ctx, "GET", url, nil)
if err != nil {
return err
}
return json.Unmarshal(raw, response)
}