Skip to content

Instantly share code, notes, and snippets.

@usirin
Created May 28, 2021 08:36
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save usirin/d1dd7b6102ea66f6d6fc95831f9b8ceb to your computer and use it in GitHub Desktop.
Save usirin/d1dd7b6102ea66f6d6fc95831f9b8ceb to your computer and use it in GitHub Desktop.
parse-repo-commits.go
package cmd
import (
"context"
"errors"
"fmt"
"os"
"strings"
"time"
githubv4 "github.com/shurcooL/githubv4"
"github.com/spf13/cobra"
"golang.org/x/oauth2"
)
const (
// go to github dashboard and get a personal key.
// https://docs.github.com/en/github/authenticating-to-github/keeping-your-account-and-data-secure/creating-a-personal-access-token
API_KEY = "..."
)
// Github GraphQL query to fetch repo commit history
//
// {
// repository(owner: "usirin", name: "layout-tree") {
// ref(qualifiedName: "master") {
// target {
// ... on Commit {
// id
// history(first: 30) {
// pageInfo {
// hasNextPage
// }
// edges {
// node {
// messageHeadline
// oid
// message
// author {
// name
// email
// date
// }
// }
// }
// }
// }
// }
// }
// }
// }
//
// query represents the query response from repositories query.
var query struct {
Viewer struct {
Login githubv4.String
CreatedAt githubv4.DateTime
}
Repository struct {
Ref struct {
Target struct {
Commit struct {
Id string
History struct {
Edges []struct {
Node struct {
MessageHeadline string
Oid string
Message string
Author struct {
Name string
Email string
Date time.Time
}
}
}
} `graphql:"history(first: 30)"`
} `graphql:"... on Commit"`
}
} `graphql:"ref(qualifiedName: $branchName)"`
} `graphql:"repository(owner: $owner, name: $repo)"`
}
var githubRepo string
var branchName string
// parseCmd represents the parse command
var parseCmd = &cobra.Command{
Use: "parse",
Short: "Parse commits of a repository",
Long: `Parses commit history of given branch for the repository`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("parse called", args)
src := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: API_KEY},
)
httpClient := oauth2.NewClient(context.Background(), src)
client := githubv4.NewClient(httpClient)
owner, repo, err := splitGithubRepo(githubRepo)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Println("user", owner)
fmt.Println("repo", repo)
err = client.Query(context.Background(), &query, map[string]interface{}{
"owner": githubv4.String(owner),
"repo": githubv4.String(repo),
"branchName": githubv4.String(branchName),
})
if err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Println(query)
},
}
// init handles command configuration
func init() {
rootCmd.AddCommand(parseCmd)
parseCmd.Flags().StringVarP(&githubRepo, "repo", "r", "", "Github repo path example: usirin/commit-log")
parseCmd.Flags().StringVarP(&branchName, "branch", "b", "main", "Branch name.")
parseCmd.MarkFlagRequired("repo")
}
// splitGithubRepo splits a github repo name to its parts.
// It will return an error if repo name is not valid.
func splitGithubRepo(repoName string) (string, string, error) {
parts := strings.Split(repoName, "/")
if len(parts) != 2 {
return "", "", errors.New("Repo name is wrong")
}
return parts[0], parts[1], nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment