github.com/vlal/goveralls@v0.0.2-0.20171114042957-b71a1e4855f8/gitinfo.go (about) 1 package main 2 3 import ( 4 "log" 5 "os" 6 "os/exec" 7 "regexp" 8 "strings" 9 ) 10 11 var remotesRE = regexp.MustCompile(`^(\S+)\s+(\S+)`) 12 13 // A Head object encapsulates information about the HEAD revision of a git repo. 14 type Head struct { 15 Id string `json:"id"` 16 AuthorName string `json:"author_name,omitempty"` 17 AuthorEmail string `json:"author_email,omitempty"` 18 CommitterName string `json:"committer_name,omitempty"` 19 CommitterEmail string `json:"committer_email,omitempty"` 20 Message string `json:"message"` 21 } 22 23 // A Remote object encapsulates information about a remote of a git repo. 24 type Remote struct { 25 Name string `json:"name"` 26 Url string `json:"url"` 27 } 28 29 // A Git object encapsulates information about a git repo. 30 type Git struct { 31 Head Head `json:"head"` 32 Branch string `json:"branch"` 33 Remotes []*Remote `json:"remotes,omitempty"` 34 } 35 36 // collectGitInfo runs several git commands to compose a Git object. 37 func collectGitInfo() *Git { 38 gitCmds := map[string][]string{ 39 "id": {"rev-parse", "HEAD"}, 40 "branch": {"rev-parse", "--abbrev-ref", "HEAD"}, 41 "aname": {"log", "-1", "--pretty=%aN"}, 42 "aemail": {"log", "-1", "--pretty=%aE"}, 43 "cname": {"log", "-1", "--pretty=%cN"}, 44 "cemail": {"log", "-1", "--pretty=%cE"}, 45 "message": {"log", "-1", "--pretty=%s"}, 46 "remotes": {"remote", "-v"}, 47 } 48 results := map[string]string{} 49 remotes := map[string]Remote{} 50 gitPath, err := exec.LookPath("git") 51 if err != nil { 52 log.Fatal(err) 53 } 54 for key, args := range gitCmds { 55 if key == "branch" { 56 if envBranch := loadBranchFromEnv(); envBranch != "" { 57 results[key] = envBranch 58 continue 59 } 60 } 61 62 cmd := exec.Command(gitPath, args...) 63 ret, err := cmd.CombinedOutput() 64 if err != nil { 65 if strings.Contains(string(ret), `Not a git repository`) { 66 return nil 67 } 68 log.Fatalf("%v: %v", err, string(ret)) 69 } 70 s := string(ret) 71 s = strings.TrimRight(s, "\n") 72 results[key] = s 73 } 74 for _, line := range strings.Split(results["remotes"], "\n") { 75 matches := remotesRE.FindAllStringSubmatch(line, -1) 76 if len(matches) != 1 { 77 continue 78 } 79 if len(matches[0]) != 3 { 80 continue 81 } 82 name := matches[0][1] 83 url := matches[0][2] 84 r := Remote{ 85 Name: name, 86 Url: url, 87 } 88 remotes[name] = r 89 } 90 h := Head{ 91 Id: results["id"], 92 AuthorName: results["aname"], 93 AuthorEmail: results["aemail"], 94 CommitterName: results["cname"], 95 CommitterEmail: results["cemail"], 96 Message: results["message"], 97 } 98 g := &Git{ 99 Head: h, 100 Branch: results["branch"], 101 } 102 for _, r := range remotes { 103 g.Remotes = append(g.Remotes, &r) 104 } 105 return g 106 } 107 108 func loadBranchFromEnv() string { 109 varNames := []string{"GIT_BRANCH", "CIRCLE_BRANCH", "TRAVIS_BRANCH", "CI_BRANCH", "APPVEYOR_REPO_BRANCH"} 110 for _, varName := range varNames { 111 if branch := os.Getenv(varName); branch != "" { 112 return branch 113 } 114 } 115 return "" 116 }