Skip to content

Commit

Permalink
feat: add number of commits check
Browse files Browse the repository at this point in the history
Signed-off-by: Andrew Rynhard <andrew@andrewrynhard.com>
  • Loading branch information
andrewrynhard committed Jul 4, 2019
1 parent b330410 commit e66888a
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 24 deletions.
49 changes: 25 additions & 24 deletions .conform.yaml
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
policies:
- type: commit
spec:
headerLength: 89
dco: true
gpg: false
imperative: true
conventional:
types:
- chore
- docs
- perf
- refactor
- style
- test
scopes:
- policy
- type: license
spec:
includeSuffixes:
- .go
header: |
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- type: commit
spec:
headerLength: 89
dco: true
gpg: false
imperative: true
maximumOfOneCommit: true
conventional:
types:
- chore
- docs
- perf
- refactor
- style
- test
scopes:
- policy
- type: license
spec:
includeSuffixes:
- .go
header: |
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
36 changes: 36 additions & 0 deletions internal/git/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"gopkg.in/src-d/go-git.v4/config"
"gopkg.in/src-d/go-git.v4/plumbing"
"gopkg.in/src-d/go-git.v4/plumbing/object"
"gopkg.in/src-d/go-git.v4/plumbing/storer"
)

// Git is a helper for git.
Expand Down Expand Up @@ -134,3 +135,38 @@ func (g *Git) SHA() (sha string, err error) {

return sha, nil
}

// AheadBehind returns the number of commits that HEAD is ahead and behind
// relative to the specified ref.
func (g *Git) AheadBehind(ref string) (ahead int, behind int, err error) {
ref1, err := g.repo.Reference(plumbing.ReferenceName(ref), false)
if err != nil {
return 0, 0, err
}

ref2, err := g.repo.Head()
if err != nil {
return 0, 0, err
}

commit2, err := object.GetCommit(g.repo.Storer, ref2.Hash())
if err != nil {
return 0, 0, nil
}

var count int
iter := object.NewCommitPreorderIter(commit2, nil, nil)
err = iter.ForEach(func(comm *object.Commit) error {
if comm.Hash != ref1.Hash() {
count++
return nil
}

return storer.ErrStop
})
if err != nil {
return 0, 0, nil
}

return count, 0, nil
}
57 changes: 57 additions & 0 deletions internal/policy/commit/check_number_of_commits.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package commit

import (
"fmt"

"github.com/autonomy/conform/internal/git"
"github.com/autonomy/conform/internal/policy"
"github.com/pkg/errors"
)

// NumberOfCommits enforces a maximum number of charcters on the commit
// header.
type NumberOfCommits struct {
ref string
ahead int
errors []error
}

// Name returns the name of the check.
func (h NumberOfCommits) Name() string {
return "Number of Commits"
}

// Message returns to check message.
func (h NumberOfCommits) Message() string {
return fmt.Sprintf("HEAD is %d commit(s) ahead of %s", h.ahead, h.ref)
}

// Errors returns any violations of the check.
func (h NumberOfCommits) Errors() []error {
return h.errors
}

// ValidateNumberOfCommits checks the header length.
func (c Commit) ValidateNumberOfCommits(g *git.Git, ref string) policy.Check {
check := &NumberOfCommits{
ref: ref,
}

var err error
check.ahead, _, err = g.AheadBehind(ref)
if err != nil {
check.errors = append(check.errors, err)
return check
}

if check.ahead > 1 {
check.errors = append(check.errors, errors.Errorf("HEAD is %d commit(s) ahead of %s", check.ahead, ref))
return check
}

return check
}
8 changes: 8 additions & 0 deletions internal/policy/commit/commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ type Commit struct {
// Imperative enforces the use of imperative verbs as the first word of a
// commit message.
Imperative bool `mapstructure:"imperative"`
// MaximumOfOneCommit enforces that the current commit is only one commit
// ahead of a specified ref.
MaximumOfOneCommit bool `mapstructure:"maximumOfOneCommit"`
// Conventional is the user specified settings for conventional commits.
Conventional *Conventional `mapstructure:"conventional"`

Expand Down Expand Up @@ -73,6 +76,7 @@ func (c *Commit) Compliance(options *policy.Options) (*policy.Report, error) {
if c.GPG {
report.AddCheck(c.ValidateGPGSign(g))
}

if c.Imperative {
report.AddCheck(c.ValidateImperative())
}
Expand All @@ -81,6 +85,10 @@ func (c *Commit) Compliance(options *policy.Options) (*policy.Report, error) {
report.AddCheck(c.ValidateConventionalCommit())
}

if c.MaximumOfOneCommit {
report.AddCheck(c.ValidateNumberOfCommits(g, "refs/heads/master"))
}

return report, nil
}

Expand Down

0 comments on commit e66888a

Please sign in to comment.