diff options
author | Ben Burwell <ben@benburwell.com> | 2019-09-13 14:49:08 -0400 |
---|---|---|
committer | Ben Burwell <ben@benburwell.com> | 2019-09-13 14:58:57 -0400 |
commit | d4eebc634e4edaa9a8789fd7e3877b4d56423293 (patch) | |
tree | 4044f97bcfc22677382b56727d1ecb240ad87f6c /repo_host.go |
initial commit0.1.0
Diffstat (limited to 'repo_host.go')
-rw-r--r-- | repo_host.go | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/repo_host.go b/repo_host.go new file mode 100644 index 0000000..2fdd4cc --- /dev/null +++ b/repo_host.go @@ -0,0 +1,92 @@ +package main + +import ( + "context" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" +) + +// A RepoHost hosts repositories, and can be queried as to whether it hosts a +// repository with a specific name. +type RepoHost interface { + HostsRepo(ctx context.Context, name string) (string, bool, error) +} + +// Sourcehut is a RepoHost +// +// https://git.sr.ht +type Sourcehut struct { + Token string // a personal access token + Username string // the username +} + +// HostsRepo implements RepoHost +func (s Sourcehut) HostsRepo(ctx context.Context, name string) (string, bool, error) { + endpoint := "https://git.sr.ht/api/~" + s.Username + "/repos/" + name + type response struct { + Name string `json:"name"` + Visibility string `json:"visibility"` + } + var repo response + if err := makeRequest(ctx, &repo, endpoint, "token "+s.Token); err != nil { + return "", false, err + } + if repo.Visibility != "public" || repo.Name == "" { + return "", false, nil + } + return "https://git.sr.ht/~" + s.Username + "/" + repo.Name, true, nil +} + +// Github is a RepoHost +// +// https://github.com +type Github struct { + Username string + Token string +} + +// HostsRepo implements RepoHost +func (g Github) HostsRepo(ctx context.Context, name string) (string, bool, error) { + endpoint := "https://api.github.com/repos/" + g.Username + "/" + name + type response struct { + URL string `json:"html_url"` + Private bool `json:"private"` + } + var repo response + if err := makeRequest(ctx, &repo, endpoint, "token "+g.Token); err != nil { + return "", false, err + } + if repo.Private || repo.URL == "" { + return "", false, nil + } + return repo.URL, true, nil +} + +func makeRequest(ctx context.Context, out interface{}, url string, auth string) error { + req, err := http.NewRequestWithContext(ctx, "GET", url, nil) + if err != nil { + return err + } + req.Header.Set("Authorization", auth) + resp, err := http.DefaultClient.Do(req) + if err != nil { + return err + } + if resp.StatusCode == http.StatusNotFound { + return nil + } + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("get %s: %s", url, resp.Status) + } + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + if err := json.Unmarshal(body, out); err != nil { + return err + } + return nil +} |