Skip to content

Commit

Permalink
(#38) Ability to ignore merge commits with --maxParents (#42)
Browse files Browse the repository at this point in the history
  • Loading branch information
llorllale authored Mar 5, 2019
1 parent 8aa4af8 commit 16d34c2
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 18 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Flags:
--body-regex=".*" Commit message body must conform to this regular expression (default: ".*").
--since="1970-01-01" A date in "yyyy-MM-dd" format starting from which commits will be analyzed (default: "1970-01-01").
--msg-file="" Only analyze the commit message found in this file (default: "").
--max-parents=1 Max number of parents a commit can have in order to be analyzed (default: 1). Useful for excluding merge commits.
```
Additionally, it will look for configurations in a file `.gitlint` in the current directory if it exists. This file's format is just the same command line flags but each on a separate line. *Flags passed through the command line take precedence.*

Expand Down
24 changes: 14 additions & 10 deletions cmd/go-gitlint/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,13 @@ import (
// Figure out a way to remove these global variables. Whatever command line
// parser we choose should be able to auto-generate usage.
var (
path = kingpin.Flag("path", `Path to the git repo (default: ".").`).Default(".").String() //nolint[gochecknoglobals]
subjectRegex = kingpin.Flag("subject-regex", `Commit subject line must conform to this regular expression (default: ".*").`).Default(".*").String() //nolint[gochecknoglobals]
subjectLength = kingpin.Flag("subject-len", "Commit subject line cannot exceed this length (default: math.MaxInt32 - 1).").Default(strconv.Itoa(math.MaxInt32 - 1)).Int() //nolint[gochecknoglobals]
bodyRegex = kingpin.Flag("body-regex", `Commit message body must conform to this regular expression (default: ".*").`).Default(".*").String() //nolint[gochecknoglobals]
since = kingpin.Flag("since", `A date in "yyyy-MM-dd" format starting from which commits will be analyzed (default: "1970-01-01").`).Default("1970-01-01").String() //nolint[gochecknoglobals]
msgFile = kingpin.Flag("msg-file", `Only analyze the commit message found in this file (default: "").`).Default("").String() //nolint[gochecknoglobals]
path = kingpin.Flag("path", `Path to the git repo (default: ".").`).Default(".").String() //nolint[gochecknoglobals]
subjectRegex = kingpin.Flag("subject-regex", `Commit subject line must conform to this regular expression (default: ".*").`).Default(".*").String() //nolint[gochecknoglobals]
subjectLength = kingpin.Flag("subject-len", "Commit subject line cannot exceed this length (default: math.MaxInt32 - 1).").Default(strconv.Itoa(math.MaxInt32 - 1)).Int() //nolint[gochecknoglobals]
bodyRegex = kingpin.Flag("body-regex", `Commit message body must conform to this regular expression (default: ".*").`).Default(".*").String() //nolint[gochecknoglobals]
since = kingpin.Flag("since", `A date in "yyyy-MM-dd" format starting from which commits will be analyzed (default: "1970-01-01").`).Default("1970-01-01").String() //nolint[gochecknoglobals]
msgFile = kingpin.Flag("msg-file", `Only analyze the commit message found in this file (default: "").`).Default("").String() //nolint[gochecknoglobals]
maxParents = kingpin.Flag("max-parents", `Max number of parents a commit can have in order to be analyzed (default: 1). Useful for excluding merge commits.`).Default("1").Int() //nolint[gochecknoglobals]
)

func main() {
Expand All @@ -60,10 +61,13 @@ func main() {
return commits.MsgIn(file)
},
func() commits.Commits {
return commits.Since(
*since,
commits.In(
repo.Filesystem(*path),
return commits.WithMaxParents(
*maxParents,
commits.Since(
*since,
commits.In(
repo.Filesystem(*path),
),
),
)
},
Expand Down
30 changes: 23 additions & 7 deletions internal/commits/commits.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@ type Commits func() []*Commit

// Commit holds data for a single git commit.
type Commit struct {
Hash string
Message string
Date time.Time
Hash string
Message string
Date time.Time
NumParents int
}

// ID is the commit's hash.
Expand All @@ -52,7 +53,7 @@ func (c *Commit) ShortID() string {

// Subject is the commit message's subject line.
func (c *Commit) Subject() string {
return strings.Split(c.Message, "\n\n")[0]
return strings.Split(c.Message, "\n")[0]
}

// Body is the commit message's body.
Expand Down Expand Up @@ -85,9 +86,10 @@ func In(repository repo.Repo) Commits {
commits = append(
commits,
&Commit{
Hash: c.Hash.String(),
Message: c.Message,
Date: c.Author.When,
Hash: c.Hash.String(),
Message: c.Message,
Date: c.Author.When,
NumParents: len(c.ParentHashes),
},
)
return nil
Expand All @@ -113,6 +115,20 @@ func Since(t string, cmts Commits) Commits {
}
}

// WithMaxParents returns commits that have at most n number of parents.
// Useful for excluding merge commits.
func WithMaxParents(n int, cmts Commits) Commits {
return func() []*Commit {
filtered := make([]*Commit, 0)
for _, c := range cmts() {
if c.NumParents <= n {
filtered = append(filtered, c)
}
}
return filtered
}
}

// MsgIn returns a single fake commit with the message read from this reader.
// This fake commit will have a fake hash and its timestamp will be time.Now().
func MsgIn(reader io.Reader) Commits {
Expand Down
15 changes: 14 additions & 1 deletion internal/commits/commits_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func TestCommitSubject(t *testing.T) {
assert.Equal(t,
(&Commit{Message: subject + "\n\ntest body"}).Subject(),
subject,
`Commit.Subject() must return the substring before the first \n\n`)
`Commit.Subject() must return the substring before the first \n`)
}

func TestCommitBody(t *testing.T) {
Expand Down Expand Up @@ -106,6 +106,19 @@ func TestMsgIn(t *testing.T) {
assert.Equal(t, "test body", commits[0].Body())
}

func TestWithMaxParents(t *testing.T) {
const max = 1
commits := WithMaxParents(max, func() []*Commit {
return []*Commit{
{NumParents: max},
{NumParents: 2},
{NumParents: 3},
}
})()
assert.Len(t, commits, 1)
assert.Equal(t, commits[0].NumParents, max)
}

// A git repo initialized and with one commit per each of the messages provided.
// This repo is created in a temporary directory; use the cleanup function
// to delete it afterwards.
Expand Down

0 comments on commit 16d34c2

Please sign in to comment.