~kota/export-github-stars

de3bba2939bf71fa6ac088136b3046b9f7966799 — Dakota Walsh 3 months ago
initial commit
6 files changed, 157 insertions(+), 0 deletions(-)

A .gitignore
A LICENSE
A README.md
A go.mod
A go.sum
A main.go
A  => .gitignore +1 -0
@@ 1,1 @@
export-github-stars

A  => LICENSE +19 -0
@@ 1,19 @@
# The Fight Club License

Copyright 2013 Benjamin Lancaster Keith

1. You do not talk about the FIGHT CLUB LICENSE.

2. You DO NOT talk about the FIGHT CLUB LICENSE.

3. If someone says "stop" or goes limp —  or taps out — the project is over.

4. Only two developers to a project.

5. One project at a time.

6. No shirts, no shoes.

7. Projects will go on as long as they have to.

8. If this is your first time reading the FIGHT CLUB LICENSE, you HAVE to license your next project under the FIGHT CLUB LICENSE.

A  => README.md +8 -0
@@ 1,8 @@
# export-github-stars
Does what is says on the tin.

# usage
1. Create yourself a new 
[personal access token](https://github.com/settings/tokens)
2. Run `go build .`
3. `./export-github-stars YOUR_TOKEN_HERE` | tee stars.txt`

A  => go.mod +20 -0
@@ 1,20 @@
module git.sr.ht/~kota/export-github-stars

go 1.19

require (
	github.com/google/go-github/v46 v46.0.0
	github.com/muesli/reflow v0.3.0
	golang.org/x/oauth2 v0.0.0-20220808172628-8227340efae7
)

require (
	github.com/golang/protobuf v1.5.2 // indirect
	github.com/google/go-querystring v1.1.0 // indirect
	github.com/mattn/go-runewidth v0.0.12 // indirect
	github.com/rivo/uniseg v0.2.0 // indirect
	golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect
	golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e // indirect
	google.golang.org/appengine v1.6.7 // indirect
	google.golang.org/protobuf v1.28.0 // indirect
)

A  => go.sum +37 -0
@@ 1,37 @@
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/go-github/v46 v46.0.0 h1:5TZiEw0Is5D9CPld0TSLPjShGr42L7PoyhUSl6KPMKM=
github.com/google/go-github/v46 v46.0.0/go.mod h1:l+/Ml209okuXUAjbvFnGZ2ntokVAhTtXvYWP8Di7OpU=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/mattn/go-runewidth v0.0.12 h1:Y41i/hVW3Pgwr8gV+J23B9YEY0zxjptBuCWEaxmAOow=
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ=
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e h1:TsQ7F31D3bUCLeqPT0u+yjp1guoArKaNKmCr22PYgTQ=
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/oauth2 v0.0.0-20220808172628-8227340efae7 h1:dtndE8FcEta75/4kHF3AbpuWzV6f1LjnLrM4pe2SZrw=
golang.org/x/oauth2 v0.0.0-20220808172628-8227340efae7/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=

A  => main.go +72 -0
@@ 1,72 @@
package main

import (
	"context"
	"flag"
	"fmt"
	"log"
	"strings"

	"github.com/google/go-github/v46/github"
	"github.com/muesli/reflow/wordwrap"
	"golang.org/x/oauth2"
)

func main() {
	flag.Parse()
	ctx := context.Background()
	ts := oauth2.StaticTokenSource(
		&oauth2.Token{AccessToken: flag.Arg(0)},
	)
	tc := oauth2.NewClient(ctx, ts)
	client := github.NewClient(tc)

	i := 1
	for {
		// List all starred repos for the authenticated user.
		opts := github.ActivityListStarredOptions{
			ListOptions: github.ListOptions{
				PerPage: 100,
				Page:    i,
			},
		}

		stars, resp, err := client.Activity.ListStarred(ctx, "", &opts)
		if err != nil {
			if _, ok := err.(*github.RateLimitError); ok {
				log.Fatalln("hit rate limit")
			}
			log.Fatalf("failed listing stars: %v\n", err)
		}

		for _, star := range stars {
			repo := star.GetRepository()

			fmt.Println(repo.GetHTMLURL())

			desc := wordwrap.String(repo.GetDescription(), 80)
			if desc != "" {
				fmt.Println("Desc:", desc)
			}

			lang := repo.GetLanguage()
			if lang == "" {
				lang = "Unknown"
			}

			fmt.Println("Lang:", lang)
			fmt.Println("Stars:", repo.GetStargazersCount())

			if len(repo.Topics) != 0 {
				topics := strings.Join(repo.Topics, ", ")
				fmt.Println("Topics:", topics)
			}

			fmt.Println()
		}
		if resp.NextPage == 0 {
			break
		}
		i += 1
	}
}