You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

92 lines
2.6 KiB

// Copyright 2021 Anthony Perkins
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"strings"
)
type apiRepo struct {
HtmlUrl string `json:"html_url"`
}
func main() {
if len(os.Args) < 2 || len(os.Args) > 3 {
fmt.Fprintln(os.Stderr, "Usage: "+os.Args[0]+" search_username [your_username:auth_token]")
os.Exit(1)
}
user := os.Args[1]
auth_token := ""
if len(os.Args) == 3 {
auth_token = os.Args[2]
}
client := http.Client{}
apiUrl := "https://api.github.com/users/" + url.PathEscape(user) + "/repos?per_page=100&page=1"
for apiUrl != "" {
apiUrl = PrintRepos(client, apiUrl, auth_token)
}
}
// PrintRepos takes an http.Client and a GitHub users/blah/repos API URL for the first page,
// and returns the URL for the next page or a blank string. For example:
// `next := PrintRepos("https://api.github.com/users/github/repos?per_page=100&page=1")`.
// This can then be run in a loop.
func PrintRepos(client http.Client, url string, auth_token string) string {
request, err := http.NewRequest("GET", url, nil)
if err != nil {
panic(err)
}
request.Header.Add("Accept", "application/vnd.github.v3+json")
request.Header.Set("User-Agent", "ghpublic/0.1")
if auth_token != "" && strings.Contains(auth_token, ":") {
creds := strings.Split(auth_token, ":")
if len(creds[0]) > 0 && len(creds[1]) > 0 {
request.SetBasicAuth(creds[0], creds[1])
}
}
response, err := client.Do(request)
if err != nil {
panic(err)
}
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
headerNext := response.Header.Get("link")
if err != nil {
panic(err)
}
var nextUrl string
if headerNext != "" {
headerNextValues := strings.Split(headerNext, ",")
for _, v := range headerNextValues {
value := strings.Split(v, ";")
if strings.Trim(value[1], " ") == "rel=\"next\"" {
nextUrl = strings.Trim(strings.Trim(strings.Trim(value[0], " "), "<"), ">")
}
}
}
var repos []apiRepo
json.Unmarshal(body, &repos)
for _, repo := range repos {
fmt.Println(repo.HtmlUrl)
}
return nextUrl
}