From 8a86bc4904aa589bf73fc259e84bdb574c6f5ea1 Mon Sep 17 00:00:00 2001 From: Andreas Wachter Date: Tue, 28 Feb 2023 19:11:36 +0100 Subject: [PATCH] backup contributed repos from github (#141) --- gitea/gitea.go | 2 +- github/github.go | 81 +++++++++++++++++++++++++++++++++++++++++- gitlab/gitlab.go | 2 +- go.mod | 2 ++ go.sum | 4 +++ gogs/gogs.go | 2 +- onedev/onedev.go | 2 +- sourcehut/sourcehut.go | 2 +- types/types.go | 1 + 9 files changed, 92 insertions(+), 6 deletions(-) diff --git a/gitea/gitea.go b/gitea/gitea.go index 7eecaf5..f411ff7 100644 --- a/gitea/gitea.go +++ b/gitea/gitea.go @@ -170,7 +170,7 @@ func Get(conf *types.Conf) ([]types.Repo, bool) { err := repo.Filter.ParseDuration() if err != nil { log.Error(). - Str("stage", "bitbucket"). + Str("stage", "gitea"). Str("url", repo.URL). Msg(err.Error()) } diff --git a/github/github.go b/github/github.go index b2bb345..ba8ed47 100644 --- a/github/github.go +++ b/github/github.go @@ -8,9 +8,72 @@ import ( "github.com/cooperspencer/gickup/types" "github.com/google/go-github/v41/github" "github.com/rs/zerolog/log" + "github.com/shurcooL/githubv4" "golang.org/x/oauth2" ) +type Repository struct { + Name string + Owner struct { + Login string + } +} + +type User struct { + Login string + RepositoriesContributedTo struct { + Nodes []Repository + PageInfo struct { + EndCursor githubv4.String + HasNextPage bool + } + } `graphql:"repositoriesContributedTo(contributionTypes: [COMMIT, PULL_REQUEST, REPOSITORY], first: 100, after: $reposCursor)"` +} + +type Query struct { + User User `graphql:"user(login: $userLogin)"` +} + +type V4Repo struct { + User string + Repository string +} + +func getv4(token, user string) []V4Repo { + repos := []V4Repo{} + tokenSource := oauth2.StaticTokenSource( + &oauth2.Token{AccessToken: token}, + ) + oauth2Client := oauth2.NewClient(context.Background(), tokenSource) + client := githubv4.NewClient(oauth2Client) + + var query Query + variables := map[string]interface{}{ + "userLogin": githubv4.String(user), // Replace with the username you want to retrieve contributed projects from + "reposCursor": (*githubv4.String)(nil), + } + for { + err := client.Query(context.Background(), &query, variables) + if err != nil { + log.Error(). + Str("stage", "github"). + Msg(err.Error()) + return []V4Repo{} + } + + projects := query.User.RepositoriesContributedTo.Nodes + for _, project := range projects { + repos = append(repos, V4Repo{User: project.Owner.Login, Repository: project.Name}) + } + + if !query.User.RepositoriesContributedTo.PageInfo.HasNextPage { + break + } + variables["reposCursor"] = githubv4.NewString(query.User.RepositoriesContributedTo.PageInfo.EndCursor) + } + return repos +} + func addWiki(r github.Repository, repo types.GenRepo, token string) types.Repo { if !(r.GetHasWiki() && repo.Wiki && types.StatRemote(r.GetCloneURL(), r.GetSSHURL(), repo)) { @@ -37,7 +100,7 @@ func Get(conf *types.Conf) ([]types.Repo, bool) { err := repo.Filter.ParseDuration() if err != nil { log.Error(). - Str("stage", "bitbucket"). + Str("stage", "github"). Str("url", repo.URL). Msg(err.Error()) } @@ -76,6 +139,7 @@ func Get(conf *types.Conf) ([]types.Repo, bool) { client = github.NewClient(tc) } + v4user := repo.User if token != "" { user, _, err := client.Users.Get(context.TODO(), "") if err != nil { @@ -88,6 +152,21 @@ func Get(conf *types.Conf) ([]types.Repo, bool) { if repo.User == user.GetLogin() { repo.User = "" + v4user = user.GetLogin() + } + } + + if token != "" && v4user != "" && repo.Contributed { + for _, r := range getv4(token, v4user) { + github_repo, _, err := client.Repositories.Get(context.Background(), r.User, r.Repository) + if err != nil { + log.Error(). + Str("stage", "github"). + Str("url", "https://github.com"). + Msg(err.Error()) + continue + } + githubrepos = append(githubrepos, github_repo) } } diff --git a/gitlab/gitlab.go b/gitlab/gitlab.go index d1215b2..4dbb863 100644 --- a/gitlab/gitlab.go +++ b/gitlab/gitlab.go @@ -93,7 +93,7 @@ func Get(conf *types.Conf) ([]types.Repo, bool) { err := repo.Filter.ParseDuration() if err != nil { log.Error(). - Str("stage", "bitbucket"). + Str("stage", "gitlab"). Str("url", repo.URL). Msg(err.Error()) } diff --git a/go.mod b/go.mod index bef3c29..da56808 100644 --- a/go.mod +++ b/go.mod @@ -35,6 +35,8 @@ require ( github.com/robfig/cron/v3 v3.0.1 github.com/rs/zerolog v1.29.0 github.com/sergi/go-diff v1.3.1 // indirect + github.com/shurcooL/githubv4 v0.0.0-20230215024106-420ad0987b9b + github.com/shurcooL/graphql v0.0.0-20220606043923-3cf50f8a0a29 // indirect github.com/ulikunitz/xz v0.5.11 // indirect github.com/xanzy/go-gitlab v0.80.2 github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect diff --git a/go.sum b/go.sum index a99f73e..0db71e6 100644 --- a/go.sum +++ b/go.sum @@ -331,6 +331,10 @@ github.com/rs/zerolog v1.29.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6us github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= +github.com/shurcooL/githubv4 v0.0.0-20230215024106-420ad0987b9b h1:i0X9yN+P00PrKM2VZ4pc7K9m4bAQWpYnQDCk+VH4BA0= +github.com/shurcooL/githubv4 v0.0.0-20230215024106-420ad0987b9b/go.mod h1:hAF0iLZy4td2EX+/8Tw+4nodhlMrwN3HupfaXj3zkGo= +github.com/shurcooL/graphql v0.0.0-20220606043923-3cf50f8a0a29 h1:B1PEwpArrNp4dkQrfxh/abbBAOZBVp0ds+fBEOUOqOc= +github.com/shurcooL/graphql v0.0.0-20220606043923-3cf50f8a0a29/go.mod h1:AuYgA5Kyo4c7HfUmvRGs/6rGlMMV/6B1bVnB9JxJEEg= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= diff --git a/gogs/gogs.go b/gogs/gogs.go index 167df38..086af61 100644 --- a/gogs/gogs.go +++ b/gogs/gogs.go @@ -139,7 +139,7 @@ func Get(conf *types.Conf) ([]types.Repo, bool) { err := repo.Filter.ParseDuration() if err != nil { log.Error(). - Str("stage", "bitbucket"). + Str("stage", "gogs"). Str("url", repo.URL). Msg(err.Error()) } diff --git a/onedev/onedev.go b/onedev/onedev.go index 9670350..8e234c9 100644 --- a/onedev/onedev.go +++ b/onedev/onedev.go @@ -21,7 +21,7 @@ func Get(conf *types.Conf) ([]types.Repo, bool) { err := repo.Filter.ParseDuration() if err != nil { log.Error(). - Str("stage", "bitbucket"). + Str("stage", "onedev"). Str("url", repo.URL). Msg(err.Error()) } diff --git a/sourcehut/sourcehut.go b/sourcehut/sourcehut.go index db29326..3e4ea3c 100644 --- a/sourcehut/sourcehut.go +++ b/sourcehut/sourcehut.go @@ -121,7 +121,7 @@ func Get(conf *types.Conf) ([]types.Repo, bool) { err := repo.Filter.ParseDuration() if err != nil { log.Error(). - Str("stage", "bitbucket"). + Str("stage", "sourcehut"). Str("url", repo.URL). Msg(err.Error()) } diff --git a/types/types.go b/types/types.go index 1754f35..54befcc 100644 --- a/types/types.go +++ b/types/types.go @@ -205,6 +205,7 @@ type GenRepo struct { CreateOrg bool `yaml:"createorg"` Visibility Visibility `yaml:"visibility"` Filter Filter `yaml:"filter"` + Contributed bool `yaml:"contributed"` } // Visibility struct