diff --git a/README.md b/README.md index f1f2acf..ac55132 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Lint your git! ## Usage ``` -llorllale:~/dev/go-gitlint$ ./gitlint --help +$ ./gitlint --help usage: gitlint [] Flags: @@ -23,6 +23,7 @@ Flags: --subject-len=SUBJECT-LEN Filters commit subjects based on length. --body-regex=BODY-REGEX Filters commit message bodies based on a regular expression. --path="." Path to the git repo ("." by default). + --since="1970-01-01" A date in "yyyy-MM-dd" format starting from which commits will be analyzed (default: "1970-01-01") ``` 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.* 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 {