Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

contributor: Change from local to github #27

Merged
merged 1 commit into from
May 22, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AUTHORS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Authors

Ce Gao <ce.gao@outlook.com>
[@gaocegege](https://github.com/gaocegege)

###### Auto generated by [gaocegege/maintainer](https://github.com/gaocegege/maintainer) on 2017-05-22
8 changes: 0 additions & 8 deletions cmd/changelog.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,6 @@ const (
changelogGeneratorCmd string = "github_changelog_generator"
)

var (
tokenValue *string
)

// changelogCmd represents the changelog command
var changelogCmd = &cobra.Command{
Use: "changelog",
Expand All @@ -51,10 +47,6 @@ In the future, maintainer will support install this dependency automatically.`,

func init() {
RootCmd.AddCommand(changelogCmd)

tokenValue = changelogCmd.PersistentFlags().String(config.Token, "", "The token in GitHub."+
"To make more than 50 requests per hour the GitHub token is required."+
"You can generate it at: https://github.com/settings/tokens/new.")
}

func changelogRun() error {
Expand Down
122 changes: 57 additions & 65 deletions cmd/contributor.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,20 @@
package cmd

import (
"context"
"errors"
"log"
"os/exec"
"strings"

"sort"
"golang.org/x/oauth2"

"fmt"

"github.com/gaocegege/maintainer/config"
"github.com/gaocegege/maintainer/repo"
"github.com/gaocegege/maintainer/util"
"github.com/google/go-github/github"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

const (
Expand All @@ -37,33 +42,14 @@ const (
)

var (
contributorPattern = []string{
"(?P<user>.*) <(?P<email>.*@.*)>",
}
errNameOrEmailNotExists = errors.New("Couldn't get the name or email of one contributor")

order *string
)

// Contributor is the type for contributor.
type Contributor struct {
Name string
Commit int
}

// ContributorSlice is the type for slice of contributors.
type ContributorSlice []*Contributor

// Len is part of sort.Interface.
func (d ContributorSlice) Len() int {
return len(d)
}

// Swap is part of sort.Interface.
func (d ContributorSlice) Swap(i, j int) {
d[i], d[j] = d[j], d[i]
}

// Less is part of sort.Interface. We use count as the value to sort by
func (d ContributorSlice) Less(i, j int) bool {
return d[i].Commit < d[j].Commit
}

// contributorCmd represents the contributor command
var contributorCmd = &cobra.Command{
Use: "contributor",
Expand All @@ -82,61 +68,67 @@ passion to contribute.`,
func init() {
RootCmd.AddCommand(contributorCmd)

order = contributorCmd.PersistentFlags().String(config.Order, orderTime, "The order to compose Authors.md."+
"(time, commit)")
order = contributorCmd.PersistentFlags().String(config.Order, orderCommit, "The order to compose Authors.md."+
"(commit)")
}

// contributorRun runs the real logic to generate AUTHORS.md.
func contributorRun() error {
// git log --format='%aN <%aE>'.
gitLogCmd := exec.Command(gitCmd, gitLogArgs, gitFormatArgs)
output, err := gitLogCmd.Output()
repo, err := repo.NewRepository()
if err != nil {
return err
log.Panicf("Error when read the information from local repository: %s\n", err)
}

// Parse output and remove duplicates.
outputStr := string(output)
outputStr = outputStr[:len(outputStr)-1]
contributors := strings.Split(outputStr, "\n")
dict := make(map[string]int)
for _, contributor := range contributors {
contributor = strings.Trim(contributor, "'")
if _, ok := dict[contributor]; ok != true {
dict[contributor] = 1
} else {
dict[contributor] = dict[contributor] + 1
token := viper.GetString(config.Token)
// Override token in CLI.
if *tokenValue != "" {
log.Println("Found token in flag, override it.")
token = *tokenValue
}
ctx := context.Background()
ts := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: token},
)
tc := oauth2.NewClient(ctx, ts)

client := github.NewClient(tc)
contributors := []*github.Contributor{}
i := 1
for {
contributorsBuf, _, err := client.Repositories.ListContributors(repo.Owner, repo.Name, &github.ListContributorsOptions{
// See https://developer.github.com/v3/repos/#list-contributors
// Anon: "true",
ListOptions: github.ListOptions{
Page: i,
PerPage: 100,
},
})
if err != nil {
return err
}
if len(contributorsBuf) == 0 {
break
}
contributors = append(contributors, contributorsBuf...)
i = i + 1
}

if err := composeByOrder(contributors); err != nil {
return err
}
return composeOrder(&dict)
return nil
}

// authorHeader returns the header to be written into AUTHORS.md.
func authorHeader() string {
return "# Authors\n\n"
}

func composeOrder(data *map[string]int) error {
contributors := make(ContributorSlice, 0, len(*data))
for k, v := range *data {
contributors = append(contributors, &Contributor{
Name: k,
Commit: v,
})
}

switch *order {
case orderCommit:
sort.Sort(sort.Reverse(contributors))
}
func composeByOrder(contributors []*github.Contributor) error {
return writeToFile(contributors)
}

func orderByCommit(contributors ContributorSlice) error {
return nil
}

func writeToFile(contributors ContributorSlice) error {
func writeToFile(contributors []*github.Contributor) error {
// Output results to AUTHORS.md.
f, err := util.OpenFile(authorFile)
if err != nil {
Expand All @@ -145,8 +137,8 @@ func writeToFile(contributors ContributorSlice) error {
if _, err := f.WriteString(authorHeader()); err != nil {
return err
}
for _, k := range contributors {
if _, err := f.WriteString(k.Name); err != nil {
for _, contributor := range contributors {
if _, err := f.WriteString(fmt.Sprintf("[@%s](%s)", *contributor.Login, *contributor.HTMLURL)); err != nil {
return err
}
if _, err := f.WriteString("\n\n"); err != nil {
Expand Down
7 changes: 6 additions & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,16 @@ import (

"log"

"github.com/gaocegege/maintainer/config"
"github.com/gaocegege/maintainer/repo"

"github.com/spf13/cobra"
"github.com/spf13/viper"
)

var (
cfgFile string
cfgFile string
tokenValue *string
// Repo stores the information in the local repository.
Repo *repo.Repository
)
Expand All @@ -50,6 +52,9 @@ func Execute() {

func init() {
cobra.OnInitialize(initConfig)
tokenValue = RootCmd.PersistentFlags().String(config.Token, "", "The token in GitHub."+
"To make more than 50 requests per hour the GitHub token is required."+
"You can generate it at: https://github.com/settings/tokens/new.")
RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.maintainer.yaml)")
}

Expand Down
21 changes: 3 additions & 18 deletions repo/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ import (
"errors"
"fmt"
"os/exec"
"regexp"

"github.com/gaocegege/maintainer/util"
)

const (
Expand Down Expand Up @@ -89,7 +90,7 @@ func getNameAndRepoName() (string, string, error) {
// getNameAndRepoName gets the name and project from local repository.
func getNameAndRepoNameFromRemote(remoteStr string) (string, string, error) {
for _, regEx := range gitRemotePattern {
paramsMap := getParams(regEx, remoteStr)
paramsMap := util.GetParams(regEx, remoteStr)
name, ok1 := paramsMap["user"]
project, ok2 := paramsMap["project"]
if ok1 != true || ok2 != true {
Expand All @@ -99,19 +100,3 @@ func getNameAndRepoNameFromRemote(remoteStr string) (string, string, error) {
}
return "", "", errNameOrProjectNotExists
}

// getParams get the params from regexp.
// See http://stackoverflow.com/questions/30483652/how-to-get-capturing-group-functionality-in-golang-regular-expressions.
func getParams(regEx, url string) (paramsMap map[string]string) {

var compRegEx = regexp.MustCompile(regEx)
match := compRegEx.FindStringSubmatch(url)

paramsMap = make(map[string]string)
for i, name := range compRegEx.SubexpNames() {
if i > 0 && i <= len(match) {
paramsMap[name] = match[i]
}
}
return
}
19 changes: 19 additions & 0 deletions util/regexutil.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package util

import "regexp"

// GetParams get the params from regexp.
// See http://stackoverflow.com/questions/30483652/how-to-get-capturing-group-functionality-in-golang-regular-expressions.
func GetParams(regEx, url string) (paramsMap map[string]string) {

var compRegEx = regexp.MustCompile(regEx)
match := compRegEx.FindStringSubmatch(url)

paramsMap = make(map[string]string)
for i, name := range compRegEx.SubexpNames() {
if i > 0 && i <= len(match) {
paramsMap[name] = match[i]
}
}
return
}