Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions .lint-go.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,12 @@ golangci:
depguard:
rules:
main:
# The house logging setup (slog through tint on a terminal, JSON
# otherwise), which the command installs in main.
# The house command line: kong for the flags, primordium's logger
# (slog, tint on a terminal) and shutdown (exit status).
allow:
- github.com/alecthomas/kong
- github.com/mycophonic/primordium/app/logger
- github.com/mycophonic/primordium/app/shutdown
exclusions:
rules:
# ---------------------------------------------------------------------------
Expand All @@ -83,11 +85,10 @@ golangci:
# Counts are the measurement at enrolment, per file and linter: 239 in 10 files.
# ---------------------------------------------------------------------------
- path: ^cmd/git-validation/main\.go$
linters: # 16 findings
- gochecknoglobals # 10
linters: # 5 findings
- forbidigo # 3
- revive # 2
- gocognit # 1
- revive # 1
- path: ^git/commits\.go$
linters: # 37 findings
- wrapcheck # 11
Expand Down
40 changes: 25 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,34 @@ go install github.com/forkcloser/git-validation/cmd/git-validation@latest
The flags

```shell
vbatts@valse ~/src/vb/git-validation (master *) $ git-validation -h
Usage of git-validation:
-D debug output
-d string
git directory to validate from (default ".")
-list-rules
list the rules registered
-range string
use this commit range instead
-run string
comma delimited list of rules to run. Defaults to all.
-v verbose
$ git-validation --help
Usage: git-validation [flags]

A way to do validation on git commits.

Flags:
-h, --help Show context-sensitive help.
--range=STRING use this commit range instead (implies
--no-travis)
--list-rules list the rules registered
--run=STRING comma delimited list of rules to run. Defaults to
all.
-v, --verbose verbose
-D, --debug debug output
-q, --quiet less output
-d, --dir="." git directory to validate from
--no-github disables Github Actions environment checks (when
env GITHUB_ACTIONS=true is set)
--no-travis disables travis environment checks (when env
TRAVIS=true is set)
--[no-]travis-pr-only when on travis, only run validations if the
CI-Build is checking pull-request build
```

The entire default rule set is run by default:

```shell
vbatts@valse ~/src/vb/git-validation (master) $ git-validation -list-rules
vbatts@valse ~/src/vb/git-validation (master) $ git-validation --list-rules
"dangling-whitespace" -- checking the presence of dangling whitespaces on line endings
"DCO" -- makes sure the commits are signed
"message_regexp" -- checks the commit message for a user provided regular expression
Expand All @@ -40,7 +50,7 @@ vbatts@valse ~/src/vb/git-validation (master) $ git-validation -list-rules
Or, specify comma-delimited rules to run:

```shell
vbatts@valse ~/src/vb/git-validation (master) $ git-validation -run DCO,short-subject
vbatts@valse ~/src/vb/git-validation (master) $ git-validation --run DCO,short-subject
* b243ca4 "README: adding install and usage" ... PASS
* d614ccf "*: run tests in a runner" ... PASS
* b9413c6 "shortsubject: add a subject length check" ... PASS
Expand Down Expand Up @@ -94,7 +104,7 @@ vbatts@valse ~/src/vb/git-validation (master) $ echo $?
Excluding paths that are out of the scope of your project:

```shell
vbatts@valse ~/src/vb/git-validation (master) $ GIT_CHECK_EXCLUDE="./vendor:./git/testdata" git-validation -q -run dangling-whitespace
vbatts@valse ~/src/vb/git-validation (master) $ GIT_CHECK_EXCLUDE="./vendor:./git/testdata" git-validation -q --run dangling-whitespace
...
```

Expand Down
109 changes: 64 additions & 45 deletions cmd/git-validation/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ package main

import (
"context"
"flag"
"fmt"
"log/slog"
"os"
"strings"

"github.com/alecthomas/kong"
"github.com/mycophonic/primordium/app/logger"
"github.com/mycophonic/primordium/app/shutdown"

_ "github.com/forkcloser/git-validation/rules/danglingwhitespace"
_ "github.com/forkcloser/git-validation/rules/dco"
Expand All @@ -17,49 +18,70 @@ import (
"github.com/forkcloser/git-validation/validate"
)

var (
flCommitRange = flag.String("range", "", "use this commit range instead (implies -no-travis)")
flListRules = flag.Bool("list-rules", false, "list the rules registered")
flRun = flag.String("run", "", "comma delimited list of rules to run. Defaults to all.")
flVerbose = flag.Bool("v", false, "verbose")
flDebug = flag.Bool("D", false, "debug output")
flQuiet = flag.Bool("q", false, "less output")
flDir = flag.String("d", ".", "git directory to validate from")
flNoGithub = flag.Bool(
"no-github",
false,
"disables Github Actions environment checks (when env GITHUB_ACTIONS=true is set)",
)
flNoTravis = flag.Bool("no-travis", false, "disables travis environment checks (when env TRAVIS=true is set)")
flTravisPROnly = flag.Bool(
"travis-pr-only",
true,
"when on travis, only run validations if the CI-Build is checking pull-request build",
)
)
// cli is the command line. The flag names are upstream's; kong spells them
// with two dashes, and keeps the one-letter ones as short flags.
type cli struct {
Range string `help:"use this commit range instead (implies --no-travis)"`
ListRules bool `help:"list the rules registered"`
Run string `help:"comma delimited list of rules to run. Defaults to all."`
Verbose bool `help:"verbose" short:"v"`
Debug bool `help:"debug output" short:"D"`
Quiet bool `help:"less output" short:"q"`
Dir string `default:"." help:"git directory to validate from" short:"d"`
NoGithub bool `help:"disables Github Actions environment checks (when env GITHUB_ACTIONS=true is set)" name:"no-github"`
NoTravis bool `help:"disables travis environment checks (when env TRAVIS=true is set)"`
TravisPROnly bool `default:"true" help:"when on travis, only run validations if the CI-Build is checking pull-request build" name:"travis-pr-only" negatable:""`
}

// errCommitsToFix is a run that found failing commits; they are printed
// already, so the exit carries no message.
var errCommitsToFix = shutdown.ExitError(1)

func main() {
flag.Parse()
var flags cli

// Parse and usage errors are kong's, printed with the usage; every failure
// exits 1, as the flag package did, and --help exits 0.
kong.Parse(&flags,
kong.Name("git-validation"),
kong.Description("A way to do validation on git commits."),
kong.UsageOnError(),
kong.Exit(func(code int) {
if code != 0 {
code = 1
}

os.Exit(code)
}),
)

configureLogger(flags.Debug, flags.Quiet)

configureLogger(*flDebug, *flQuiet)
// shutdown runs the command and exits with the status an ExitError asks
// for, silently, and 1 for any other error, which it logs.
shutdown.Run(shutdown.SetDefaults(context.Background()), func(context.Context) error {
return run(&flags)
})
}

if *flQuiet {
func run(flags *cli) error {
if flags.Quiet {
if err := os.Setenv("QUIET", "1"); err != nil {
exitOn("quiet output", err)
return fmt.Errorf("quiet output: %w", err)
}
}

if *flListRules {
if flags.ListRules {
for _, r := range validate.RegisteredRules {
fmt.Printf("%q -- %s\n", r.Name, r.Description)
}

return
return nil
}

if *flTravisPROnly && strings.ToLower(os.Getenv("TRAVIS_PULL_REQUEST")) == "false" {
fmt.Printf("only to check travis PR builds and this not a PR build. yielding.\n")
return
if flags.TravisPROnly && strings.ToLower(os.Getenv("TRAVIS_PULL_REQUEST")) == "false" {
fmt.Println("only to check travis PR builds and this not a PR build. yielding.")
return nil
}

// rules to be used
Expand All @@ -72,43 +94,46 @@ func main() {
}
}
// or reduce the set being run to what the user provided
if *flRun != "" {
rules = validate.FilterRules(validate.RegisteredRules, validate.SanitizeFilters(*flRun))
if flags.Run != "" {
rules = validate.FilterRules(validate.RegisteredRules, validate.SanitizeFilters(flags.Run))
}

slog.Debug("rules to run", "rules", ruleNames(rules))

commitRange := *flCommitRange
commitRange := flags.Range
if commitRange == "" {
if strings.ToLower(os.Getenv("TRAVIS")) == "true" && !*flNoTravis {
if strings.ToLower(os.Getenv("TRAVIS")) == "true" && !flags.NoTravis {
if os.Getenv("TRAVIS_COMMIT_RANGE") != "" {
commitRange = strings.Replace(os.Getenv("TRAVIS_COMMIT_RANGE"), "...", "..", 1)
} else if os.Getenv("TRAVIS_COMMIT") != "" {
commitRange = os.Getenv("TRAVIS_COMMIT")
}
}
// https://docs.github.com/en/actions/reference/environment-variables
if strings.ToLower(os.Getenv("GITHUB_ACTIONS")) == "true" && !*flNoGithub {
if strings.ToLower(os.Getenv("GITHUB_ACTIONS")) == "true" && !flags.NoGithub {
commitRange = fmt.Sprintf("%s..%s", os.Getenv("GITHUB_SHA"), "HEAD")
}
}

slog.Info("using commit range", "range", commitRange)

runner, err := validate.NewRunner(*flDir, rules, commitRange, *flVerbose)
runner, err := validate.NewRunner(flags.Dir, rules, commitRange, flags.Verbose)
if err != nil {
exitOn("preparing the run", err)
return fmt.Errorf("preparing the run: %w", err)
}

if err := runner.Run(); err != nil {
exitOn("validating commits", err)
return fmt.Errorf("validating commits: %w", err)
}

_, fail := runner.Results.PassFail()
if fail > 0 {
fmt.Printf("%d commits to fix\n", fail)
os.Exit(1)

return errCommitsToFix
}

return nil
}

// configureLogger installs the process-wide slog handler through primordium:
Expand All @@ -127,12 +152,6 @@ func configureLogger(debug, quiet bool) {
logger.SetDefaultsForLogger(context.Background(), level)
}

// exitOn logs err with the step that failed and exits 1.
func exitOn(step string, err error) {
slog.Error("git-validation failed", "step", step, "err", err)
os.Exit(1)
}

func ruleNames(rules []validate.Rule) []string {
names := make([]string, 0, len(rules))
for _, rule := range rules {
Expand Down
5 changes: 4 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ module github.com/forkcloser/git-validation

go 1.26.0

require github.com/mycophonic/primordium v0.15.0
require (
github.com/alecthomas/kong v1.16.1
github.com/mycophonic/primordium v0.15.0
)

require (
github.com/lmittmann/tint v1.2.1 // indirect
Expand Down
8 changes: 8 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0=
github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
github.com/alecthomas/kong v1.16.1 h1:ixhCt93XkJ98kGposQ54+bl0IK6XwqB40AsMynU7Z8E=
github.com/alecthomas/kong v1.16.1/go.mod h1:wrlbXem1CWqUV5Vbmss5ISYhsVPkBb1Yo7YKJghju2I=
github.com/alecthomas/repr v0.5.2 h1:SU73FTI9D1P5UNtvseffFSGmdNci/O6RsqzeXJtP0Qs=
github.com/alecthomas/repr v0.5.2/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
github.com/lmittmann/tint v1.2.1 h1:zOadah+f+nSm3jZM044jOsqh0+vSfgG/d9Ota9a/TLE=
github.com/lmittmann/tint v1.2.1/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE=
github.com/mattn/go-isatty v0.0.24 h1:tGZZoVgT/KiqK1c8ocVLeDS8BSWMRd47J3Lbz7vsReI=
Expand Down
Loading