From e5eff3a4409762ccf8c9a1fe6bdbf7e6b8570a1b Mon Sep 17 00:00:00 2001 From: George Aristy Date: Sun, 3 Mar 2019 09:05:35 -0500 Subject: [PATCH] (#31) --since filter --- cmd/go-gitlint/main.go | 12 +++++++++--- internal/commits/commits.go | 20 ++++++++++++++++++++ internal/commits/commits_test.go | 23 +++++++++++++++++++++++ internal/issues/filters.go | 4 ++++ 4 files changed, 56 insertions(+), 3 deletions(-) diff --git a/cmd/go-gitlint/main.go b/cmd/go-gitlint/main.go index 5aa9a96..bde81bf 100644 --- a/cmd/go-gitlint/main.go +++ b/cmd/go-gitlint/main.go @@ -27,7 +27,10 @@ import ( // They promote coupling across different components inside the same package. // 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 ("." by default).`).Default(".").String() //nolint[gochecknoglobals] +var ( + path = kingpin.Flag("path", `Path to the git repo ("." by 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] +) func main() { configure() @@ -37,8 +40,11 @@ func main() { os.Stdout, "\n", issues.Collected( issues.Filters(), - commits.In( - repo.Filesystem(*path), + commits.Since( + *since, + commits.In( + repo.Filesystem(*path), + ), ), ), )(), diff --git a/internal/commits/commits.go b/internal/commits/commits.go index d2b4bcf..3b69bf5 100644 --- a/internal/commits/commits.go +++ b/internal/commits/commits.go @@ -16,6 +16,7 @@ package commits import ( "strings" + "time" "github.com/llorllale/go-gitlint/internal/repo" git "gopkg.in/src-d/go-git.v4" @@ -34,6 +35,7 @@ type Commits func() []*Commit type Commit struct { Hash string Message string + Date time.Time } // ID is the commit's hash. @@ -83,6 +85,7 @@ func In(repository repo.Repo) Commits { &Commit{ Hash: c.Hash.String(), Message: c.Message, + Date: c.Author.When, }, ) return nil @@ -90,3 +93,20 @@ func In(repository repo.Repo) Commits { return commits } } + +// Since returns commits authored since time t (format: yyyy-MM-dd). +func Since(t string, cmts Commits) Commits { + return func() []*Commit { + start, err := time.Parse("2006-01-02", t) + if err != nil { + panic(err) + } + filtered := make([]*Commit, 0) + for _, c := range cmts() { + if !c.Date.Before(start) { + filtered = append(filtered, c) + } + } + return filtered + } +} diff --git a/internal/commits/commits_test.go b/internal/commits/commits_test.go index 4b5ad2b..c2837f4 100644 --- a/internal/commits/commits_test.go +++ b/internal/commits/commits_test.go @@ -26,6 +26,7 @@ import ( "github.com/google/uuid" "github.com/llorllale/go-gitlint/internal/repo" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" git "gopkg.in/src-d/go-git.v4" "gopkg.in/src-d/go-git.v4/plumbing/object" ) @@ -75,6 +76,28 @@ func TestIn(t *testing.T) { } } +func TestSince(t *testing.T) { + before, err := time.Parse("2006-01-02", "2017-10-25") + require.NoError(t, err) + since, err := time.Parse("2006-01-02", "2019-01-01") + require.NoError(t, err) + after, err := time.Parse("2006-01-02", "2019-03-03") + require.NoError(t, err) + commits := Since( + "2019-01-01", + func() []*Commit { + return []*Commit{ + {Date: before}, + {Date: since}, + {Date: after}, + } + }, + )() + assert.Len(t, commits, 2) + assert.Contains(t, commits, &Commit{Date: since}) + assert.Contains(t, commits, &Commit{Date: after}) +} + // 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. diff --git a/internal/issues/filters.go b/internal/issues/filters.go index 2a014ed..897a3f3 100644 --- a/internal/issues/filters.go +++ b/internal/issues/filters.go @@ -34,6 +34,10 @@ var ( type Filter func(*commits.Commit) Issue // Filters returns all filters configured by the user. +// @todo #31 Function issues.Filters() can be removed by providing +// default values for each filter that will effectively render them +// disabled. For example, OfSubjectRegex() can be effectively disabled +// by using ".*" as regex. func Filters() []Filter { filters := make([]Filter, 0) if subjectRegex != nil {