Skip to content

Commit

Permalink
contributing: Get owner and project from git
Browse files Browse the repository at this point in the history
Signed-off-by: Ce Gao <ce.gao@outlook.com>
  • Loading branch information
gaocegege committed May 1, 2017
1 parent d4440d7 commit 9350620
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 3 deletions.
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,4 @@ For the why part, if no specific reason for the change,
you can use one of some generic reasons like "Improve documentation.",
"Improve performance.", "Improve robustness.", "Improve test coverage."

###### Auto generated by [gaocegege/maintainer](https://github.com/gaocegege/maintainer) on 2017-04-27
###### Auto generated by [gaocegege/maintainer](https://github.com/gaocegege/maintainer) on 2017-05-01
6 changes: 6 additions & 0 deletions cmd/contributing.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package cmd
import (
"log"

"github.com/gaocegege/maintainer/repo"
"github.com/gaocegege/maintainer/util"
"github.com/spf13/cobra"
)
Expand Down Expand Up @@ -49,6 +50,11 @@ func init() {

// contributingRun runs the real logic to generate CONTRIBUTING.md.
func contributingRun() error {
repo, err := repo.NewRepository()
if err != nil {
log.Panicf("Error when read the information from local repository: %s\n", err)
}
log.Print(repo.String())
// Output results to AUTHORS.md.
f, err := util.OpenFile(contributingFile)
if err != nil {
Expand Down
12 changes: 10 additions & 2 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,19 @@ import (

"log"

"github.com/gaocegege/maintainer/repo"

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

var cfgFile string
var (
cfgFile string
// Repo stores the information in the local repository.
Repo *repo.Repository
)

// This represents the base command when called without any subcommands
// RootCmd represents the base command when called without any subcommands
var RootCmd = &cobra.Command{
Use: "maintainer",
Short: "Help you to be a qualified maintainer.",
Expand Down Expand Up @@ -61,5 +67,7 @@ func initConfig() {
// If a config file is found, read it in.
if err := viper.ReadInConfig(); err == nil {
log.Println("Using config file:", viper.ConfigFileUsed())
} else {
log.Println("There is no config file defined.")
}
}
117 changes: 117 additions & 0 deletions repo/repo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
// Copyright © 2017 Maintainer Authors
//
// 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 repo

import (
"errors"
"fmt"
"os/exec"
"regexp"
)

const (
gitCmd string = "git"
gitConfigArgs string = "config"
gitConfigGetArgs string = "--get"
gitConfigGetRemoteArgs string = "remote.origin.url"
)

var (
gitRemotePattern = []string{
`.*(?:[:\/])(?P<user>(?:-|\w|\.)*)\/(?P<project>(?:-|\w|\.)*)(?:\.git).*`,
`.*\/(?P<user>(?:-|\w|\.)*)\/(?P<project>(?:-|\w|\.)*).*`,
}

errNameOrProjectNotExists = errors.New("Couldn't get the URL of this repository")

singleton *Repository
)

// Repository is the type for the local repository.
type Repository struct {
Owner string
Name string
}

// NewRepository returns a new Repository.
func NewRepository() (*Repository, error) {
if singleton != nil {
return singleton, nil
}

name, project, err := getNameAndRepoName()
if err != nil {
return nil, err
}

singleton = &Repository{
Owner: name,
Name: project,
}
return singleton, nil
}

// String returns the information of a local repository.
func (r *Repository) String() string {
return fmt.Sprintf("Local Repository Information: \n\tOwner: %s\n\tName: %s\n", r.Owner, r.Name)
}

// See https://github.com/skywinder/github-changelog-generator/blob/master/lib/github_changelog_generator/parser.rb#L312.
func getNameAndRepoName() (string, string, error) {
cmd := exec.Command(gitCmd, gitConfigArgs, gitConfigGetArgs, gitConfigGetRemoteArgs)
output, err := cmd.Output()
if err != nil {
return "", "", err
}
outputStr := string(output)

// get the name and project.
name, project, err := getNameAndRepoNameFromRemote(outputStr)
if err != nil {
return "", "", err
}

return name, project, nil
}

// getNameAndRepoName gets the name and project from local repository.
func getNameAndRepoNameFromRemote(remoteStr string) (string, string, error) {
for _, regEx := range gitRemotePattern {
paramsMap := getParams(regEx, remoteStr)
name, ok1 := paramsMap["user"]
project, ok2 := paramsMap["project"]
if ok1 != true || ok2 != true {
continue
}
return name, project, nil
}
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
}

0 comments on commit 9350620

Please sign in to comment.