aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/vbatts/git-validation/git
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/vbatts/git-validation/git')
-rw-r--r--vendor/github.com/vbatts/git-validation/git/commits.go192
1 files changed, 192 insertions, 0 deletions
diff --git a/vendor/github.com/vbatts/git-validation/git/commits.go b/vendor/github.com/vbatts/git-validation/git/commits.go
new file mode 100644
index 000000000..52af99789
--- /dev/null
+++ b/vendor/github.com/vbatts/git-validation/git/commits.go
@@ -0,0 +1,192 @@
+package git
+
+import (
+ "fmt"
+ "os"
+ "os/exec"
+ "strings"
+
+ version "github.com/hashicorp/go-version"
+ "github.com/sirupsen/logrus"
+)
+
+// Commits returns a set of commits.
+// If commitrange is a git still range 12345...54321, then it will be isolated set of commits.
+// If commitrange is a single commit, all ancestor commits up through the hash provided.
+// If commitrange is an empty commit range, then nil is returned.
+func Commits(commitrange string) ([]CommitEntry, error) {
+ cmdArgs := []string{"git", "--no-pager", "log", `--pretty=format:%H`, commitrange}
+ if debug() {
+ logrus.Infof("[git] cmd: %q", strings.Join(cmdArgs, " "))
+ }
+ output, err := exec.Command(cmdArgs[0], cmdArgs[1:]...).Output()
+ if err != nil {
+ logrus.Errorf("mm[git] cmd: %q", strings.Join(cmdArgs, " "))
+ return nil, err
+ }
+ if len(output) == 0 {
+ return nil, nil
+ }
+ commitHashes := strings.Split(strings.TrimSpace(string(output)), "\n")
+ commits := make([]CommitEntry, len(commitHashes))
+ for i, commitHash := range commitHashes {
+ c, err := LogCommit(commitHash)
+ if err != nil {
+ return commits, err
+ }
+ commits[i] = *c
+ }
+ return commits, nil
+}
+
+// FieldNames are for the formating and rendering of the CommitEntry structs.
+// Keys here are from git log pretty format "format:..."
+var FieldNames = map[string]string{
+ "%h": "abbreviated_commit",
+ "%p": "abbreviated_parent",
+ "%t": "abbreviated_tree",
+ "%aD": "author_date",
+ "%aE": "author_email",
+ "%aN": "author_name",
+ "%b": "body",
+ "%H": "commit",
+ "%N": "commit_notes",
+ "%cD": "committer_date",
+ "%cE": "committer_email",
+ "%cN": "committer_name",
+ "%e": "encoding",
+ "%P": "parent",
+ "%D": "refs",
+ "%f": "sanitized_subject_line",
+ "%GS": "signer",
+ "%GK": "signer_key",
+ "%s": "subject",
+ "%G?": "verification_flag",
+}
+
+func gitVersion() (string, error) {
+ cmd := exec.Command("git", "version")
+ cmd.Stderr = os.Stderr
+ buf, err := cmd.Output()
+ if err != nil {
+ return "", err
+ }
+ return strings.Fields(string(buf))[2], nil
+}
+
+// https://github.com/vbatts/git-validation/issues/37
+var versionWithExcludes = "1.9.5"
+
+func gitVersionNewerThan(otherV string) (bool, error) {
+ gv, err := gitVersion()
+ if err != nil {
+ return false, err
+ }
+ v1, err := version.NewVersion(gv)
+ if err != nil {
+ return false, err
+ }
+ v2, err := version.NewVersion(otherV)
+ if err != nil {
+ return false, err
+ }
+ return v2.Equal(v1) || v2.LessThan(v1), nil
+}
+
+// Check warns if changes introduce whitespace errors.
+// Returns non-zero if any issues are found.
+func Check(commit string) ([]byte, error) {
+ args := []string{
+ "--no-pager", "log", "--check",
+ fmt.Sprintf("%s^..%s", commit, commit),
+ }
+ if excludeEnvList := os.Getenv("GIT_CHECK_EXCLUDE"); excludeEnvList != "" {
+ gitNewEnough, err := gitVersionNewerThan(versionWithExcludes)
+ if err != nil {
+ return nil, err
+ }
+ if gitNewEnough {
+ excludeList := strings.Split(excludeEnvList, ":")
+ for _, exclude := range excludeList {
+ if exclude == "" {
+ continue
+ }
+ args = append(args, "--", ".", fmt.Sprintf(":(exclude)%s", exclude))
+ }
+ }
+ }
+ cmd := exec.Command("git", args...)
+ if debug() {
+ logrus.Infof("[git] cmd: %q", strings.Join(cmd.Args, " "))
+ }
+ cmd.Stderr = os.Stderr
+ return cmd.Output()
+}
+
+// Show returns the diff of a commit.
+//
+// NOTE: This could be expensive for very large commits.
+func Show(commit string) ([]byte, error) {
+ cmd := exec.Command("git", "--no-pager", "show", commit)
+ if debug() {
+ logrus.Infof("[git] cmd: %q", strings.Join(cmd.Args, " "))
+ }
+ cmd.Stderr = os.Stderr
+ return cmd.Output()
+}
+
+// CommitEntry represents a single commit's information from `git`.
+// See also FieldNames
+type CommitEntry map[string]string
+
+// LogCommit assembles the full information on a commit from its commit hash
+func LogCommit(commit string) (*CommitEntry, error) {
+ c := CommitEntry{}
+ for k, v := range FieldNames {
+ cmd := exec.Command("git", "--no-pager", "log", "-1", `--pretty=format:`+k+``, commit)
+ if debug() {
+ logrus.Infof("[git] cmd: %q", strings.Join(cmd.Args, " "))
+ }
+ cmd.Stderr = os.Stderr
+ out, err := cmd.Output()
+ if err != nil {
+ logrus.Errorf("[git] cmd: %q", strings.Join(cmd.Args, " "))
+ return nil, err
+ }
+ c[v] = strings.TrimSpace(string(out))
+ }
+
+ return &c, nil
+}
+
+func debug() bool {
+ return len(os.Getenv("DEBUG")) > 0
+}
+
+// FetchHeadCommit returns the hash of FETCH_HEAD
+func FetchHeadCommit() (string, error) {
+ cmdArgs := []string{"git", "--no-pager", "rev-parse", "--verify", "FETCH_HEAD"}
+ if debug() {
+ logrus.Infof("[git] cmd: %q", strings.Join(cmdArgs, " "))
+ }
+ output, err := exec.Command(cmdArgs[0], cmdArgs[1:]...).Output()
+ if err != nil {
+ logrus.Errorf("[git] cmd: %q", strings.Join(cmdArgs, " "))
+ return "", err
+ }
+ return strings.TrimSpace(string(output)), nil
+}
+
+// HeadCommit returns the hash of HEAD
+func HeadCommit() (string, error) {
+ cmdArgs := []string{"git", "--no-pager", "rev-parse", "--verify", "HEAD"}
+ if debug() {
+ logrus.Infof("[git] cmd: %q", strings.Join(cmdArgs, " "))
+ }
+ output, err := exec.Command(cmdArgs[0], cmdArgs[1:]...).Output()
+ if err != nil {
+ logrus.Errorf("[git] cmd: %q", strings.Join(cmdArgs, " "))
+ return "", err
+ }
+ return strings.TrimSpace(string(output)), nil
+}