Skip to content

Commit 762b32e

Browse files
author
Nils Wogatzky
authored
Add configuration na convenience sub commands (#1)
* wip: integrated config, tests passing. some coverage missing * * solved edge case "initial commit in a new git repository" by making a call to "git log" to determine branch name, when "git branch" returned empty input in a fresh initialzed repo. * simplyfied config * add diagnostics output and update readme * add several convinience sub commands (diagnostics, install, uninstall, test) cleaned up unnecessary files, moved hook files from root into hook package * prepare custom docker file, cleanup makefile from deprecated tools * remove appveyor
1 parent 0cd72fa commit 762b32e

38 files changed

+1728
-385
lines changed

.docker/Dockerfile

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
FROM golang:1.10
2+
3+
WORKDIR /go/src/github.com/Oppodelldog/git-commit-hook
4+
5+
RUN go get -u gopkg.in/alecthomas/gometalinter.v2 && \
6+
go get -u github.com/golang/dep/cmd/dep && \
7+
go get -u golang.org/x/tools/cmd/goimports && \
8+
go get -u github.com/mattn/goveralls
9+
10+
RUN apt-get update && \
11+
apt-get install -y libpcre++-dev

.drone.yml

+5-14
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,10 @@
11
workspace:
2-
base: /go
3-
path: src/github.com/Oppodelldog/git-commit-hook
2+
base: /go/src/github.com/Oppodelldog/git-commit-hook
3+
path: /
44

55
pipeline:
66
build:
7-
image: golang:1.9.4
7+
image: oppodelldog/git-commit-hook:latest
8+
pull: true
89
commands:
9-
- go get -u github.com/golang/dep/cmd/dep
10-
- dep ensure
11-
- go get ./...
12-
- go get github.com/mattn/goveralls
13-
- goveralls -service drone.io -repotoken BddPGJN9lAFBYHLGI5mIHLjZVJlD74n3X
14-
- go build
15-
16-
matrix:
17-
GO_VERSION:
18-
- latest
19-
- "1.9"
10+
- make ci

Gopkg.lock

+51
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Gopkg.toml

+13-1
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,22 @@
2020
# version = "2.4.0"
2121

2222

23+
[[constraint]]
24+
name = "github.com/Oppodelldog/filediscovery"
25+
version = "0.1.0"
26+
27+
[[constraint]]
28+
branch = "master"
29+
name = "github.com/glenn-brown/golang-pkg-pcre"
30+
2331
[[constraint]]
2432
name = "github.com/pkg/errors"
2533
version = "0.8.0"
2634

2735
[[constraint]]
2836
name = "github.com/stretchr/testify"
29-
version = "1.2.1"
37+
version = "1.2.2"
38+
39+
[[constraint]]
40+
name = "gopkg.in/yaml.v2"
41+
version = "2.2.1"

Makefile

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
1-
SOURCE_FILES?=$$(go list ./... | grep -v /vendor/)
2-
TEST_PATTERN?=.
3-
TEST_OPTIONS?=-race -covermode=atomic -coverprofile=coverage.txt
4-
51
setup: ## Install all the build and lint dependencies
62
go get -u gopkg.in/alecthomas/gometalinter.v2
73
go get -u github.com/golang/dep/cmd/dep
8-
go get -u golang.org/x/tools/cmd/cover
94
go get -u golang.org/x/tools/cmd/goimports
105
dep ensure
116
gometalinter --install --update
127

138
test: ## Run all the tests
14-
gotestcover $(TEST_OPTIONS) $(SOURCE_FILES) -run $(TEST_PATTERN) -timeout=1m
9+
echo 'mode: atomic' > coverage.txt && go list ./... | xargs -n1 -I{} sh -c 'go test -race -covermode=atomic -coverprofile=coverage.tmp {} && tail -n +2 coverage.tmp >> coverage.txt' && rm coverage.tmp
1510

1611
cover: test ## Run all the tests and opens the coverage report
1712
go tool cover -html=coverage.txt
@@ -41,9 +36,15 @@ lint: ## Run all the linters
4136
--deadline=10m \
4237
./...
4338

44-
ci: lint test ## Run all the tests and code checks
39+
ci: ## Run all the tests and code checks
40+
dep ensure
41+
go get ./...
42+
go get github.com/mattn/goveralls
43+
goveralls -service drone.io -repotoken BddPGJN9lAFBYHLGI5mIHLjZVJlD74n3X
44+
go build cmd/main.go
4545

4646
build: ## build binary to .build folder
47+
rm -f .build/git-commit-hook
4748
go build -o ".build/git-commit-hook" cmd/main.go
4849

4950
install: ## Install to <gopath>/src
@@ -52,7 +53,6 @@ install: ## Install to <gopath>/src
5253
build-release: ## builds the checked out version into the .release/${tag} folder
5354
.release/build.sh
5455

55-
5656
# Self-Documented Makefile see https://marmelab.com/blog/2016/02/29/auto-documented-makefile.html
5757
help:
5858
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)

README.md

+60-12
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,72 @@
1+
[![Go Report Card](https://goreportcard.com/badge/github.com/Oppodelldog/git-commit-hook)](https://goreportcard.com/report/github.com/Oppodelldog/git-commit-hook) [![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://raw.githubusercontent.com/Oppodelldog/git-commit-hook/master/LICENSE) [![Linux build](http://nulldog.de:12080/api/badges/Oppodelldog/git-commit-hook/status.svg)](http://nulldog.de:12080/Oppodelldog/git-commit-hook) [![Coverage Status](https://coveralls.io/repos/github/Oppodelldog/git-commit-hook/badge.svg?branch=master)](https://coveralls.io/github/Oppodelldog/git-commit-hook?branch=master)
2+
13
# git-commit-hook
4+
> configureable git commit hook
5+
6+
7+
**Customize commit messages dynamically with templating**
8+
9+
**Validate commit message**
10+
11+
### 1. install
12+
#### Download
13+
downlod the binary and ensure your user has execution permissions
14+
#### Install
15+
Copy or link the binary into your git repositories ```hooks``` folder
16+
(Project/.git/hooks), rename it to ```commit-msg```
17+
18+
Or create a symlink:
19+
```ln -sf ~/Downloads/git-commit-hook ~/MyProject/.git/hooks/commit-msg```
20+
21+
### 2. Configure
22+
```yaml
23+
"project xyz":
24+
# path to the git repository
25+
path: "/home/nils/projects/xyz/.git"
26+
27+
# define types of branch and a pattern to identify the type for the current branch you are working on
28+
branch:
29+
master: "^(origin\\/)*master"
30+
31+
# define a commit message template per branch type, or as here for all (*) branch types
32+
template:
33+
"*": "{.BranchName}: {.CommitMessage}"
34+
35+
# define validation rules per branch type
36+
validation:
37+
master:
38+
"(?m)(?:\\s|^|/)(([A-Z](_)*)+-[0-9]+)([\\s,;:!.-]|$)" : "valid ticket ID"
39+
```
40+
There are several places the configuration will be searched at, but one thing is for sure, the config file
41+
must be named ```git-commit-hook.yaml```.
242

3-
[![Go Report Card](https://goreportcard.com/badge/github.com/Oppodelldog/git-commit-hook)](https://goreportcard.com/report/github.com/Oppodelldog/git-commit-hook) [![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://raw.githubusercontent.com/Oppodelldog/git-commit-hook/master/LICENSE) [![Linux build](http://nulldog.de:12080/api/badges/Oppodelldog/git-commit-hook/status.svg)](http://nulldog.de:12080/Oppodelldog/git-commit-hook) [![Windows build](https://ci.appveyor.com/api/projects/status/qpe2889fbk1bw7lf/branch/master?svg=true)](https://ci.appveyor.com/project/Oppodelldog/git-commit-hook/branch/master) [![Coverage Status](https://coveralls.io/repos/github/Oppodelldog/git-commit-hook/badge.svg?branch=master)](https://coveralls.io/github/Oppodelldog/git-commit-hook?branch=master)
43+
Here are some places the configuration will be searched at:
44+
* **~/.config/git-commit-hook**
45+
* inside the **git repository** you commit in (also in subfolders **.git**, **.git/hooks**)
446

5-
**Problem:** I forget to add ticket numbers to commit messages or I take the wrong ticket ID.
47+
Watch out the test [fixture](config/test-data.yaml) for full feature sample
648

7-
**Solution:** a custom git-hook that prepends the current branch-name to every commit message.
49+
### 3. Commit
50+
You can do it on your own, I know that!!
851

9-
The implementation and rules are tightly coupled to **git flow** used with **jira**.
52+
---
1053

11-
The intention is on the one hand to make life easier when working on features.
12-
On the other hand the intention must be to not allow commits to non-fetaure branches without having a valid ticket reference.
54+
### Configuration check
55+
to check if the git hook is installed and configured correctly, just call the command from
56+
your repository like this:
57+
```.git/hooks/commit-msg```
1358

14-
### So here are the rules
59+
The output will be something like this:
1560

16-
* At least there must always be a non empty commit message.
61+
git-commit-hook - parsed configuration
1762

18-
* When you are committing to a **feature** branch
1963

20-
the hook will preprend the branch name to the commit message
64+
branch types:
65+
master : ^(origin\/)*master
2166

22-
* When you are committing to a non feature branch, lets say **develop** for a quick fix, **release/v0.1.1** for a release fix or a **hotfix**
67+
branch type templates:
68+
master : {{.CommitMessage}} - whatever !!! {{.BranchName}}
2369

24-
you have to enter a valid feature reference.
70+
branch type validation:
71+
master :
72+
(?m)^.*(#\d*)+.*$ : must have a ticket reference (eg. #267)

appveyor.yml

-38
This file was deleted.

cmd/main.go

+58-6
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,78 @@
11
package main
22

33
import (
4-
"fmt"
5-
64
"os"
75

8-
"github.com/Oppodelldog/git-commit-hook"
6+
"fmt"
7+
8+
"github.com/Oppodelldog/git-commit-hook/config"
9+
"github.com/Oppodelldog/git-commit-hook/hook"
10+
"github.com/Oppodelldog/git-commit-hook/subcommand"
11+
"github.com/pkg/errors"
912
)
1013

11-
type rewriteCommitMessageFuncDef func(string) error
14+
type callWithIntResult func() int
15+
type rewriteCommitMessageFuncDef func(string, hook.CommitMessageModifier) error
1216
type exitFuncDef func(code int)
1317

14-
var rewriteCommitMessageFunc = rewriteCommitMessageFuncDef(gitcommithook.RewriteCommitMessage)
18+
var diagnosticsFunc = callWithIntResult(subcommand.Diagnostics)
19+
var testFunc = callWithIntResult(subcommand.Test)
20+
var installFunc = callWithIntResult(subcommand.Install)
21+
var uninstallFunc = callWithIntResult(subcommand.Uninstall)
22+
var rewriteCommitMessageFunc = rewriteCommitMessageFuncDef(hook.RewriteCommitMessage)
1523
var exitFunc = exitFuncDef(os.Exit)
1624

1725
func main() {
26+
if len(os.Args) < 2 {
27+
fmt.Println("too few arguments")
28+
fmt.Println("")
29+
fmt.Println("diag - gives diagnostic output of configuration")
30+
fmt.Println("install - helps to install git-commit-hook")
31+
fmt.Println("uninstall - helps to uninstall git-commit-hook")
32+
fmt.Println("test - helps to test configuration with manual inputs")
33+
exitFunc(0)
34+
return
35+
}
36+
37+
if os.Args[1] == "test" {
38+
result := testFunc()
39+
exitFunc(result)
40+
return
41+
} else if os.Args[1] == "install" {
42+
result := installFunc()
43+
exitFunc(result)
44+
return
45+
} else if os.Args[1] == "uninstall" {
46+
result := uninstallFunc()
47+
exitFunc(result)
48+
return
49+
} else if os.Args[1] == "diag" {
50+
result := diagnosticsFunc()
51+
exitFunc(result)
52+
return
53+
}
54+
1855
commitMessageFile := os.Args[1]
19-
err := rewriteCommitMessageFunc(commitMessageFile)
56+
if commitMessageFile == "" {
57+
fmt.Print(errors.New("no commit message file passed as parameter 1"))
58+
exitFunc(1)
59+
return
60+
}
61+
62+
projectConfiguration, err := config.LoadProjectConfigurationFromCommitMessageFileDir(commitMessageFile)
63+
if err != nil {
64+
fmt.Print(err)
65+
exitFunc(1)
66+
return
67+
}
68+
69+
commitMessageModifier := hook.NewCommitMessageModifier(projectConfiguration)
70+
err = rewriteCommitMessageFunc(commitMessageFile, commitMessageModifier)
2071
if err != nil {
2172
fmt.Print(err)
2273
exitFunc(1)
2374
return
2475
}
76+
2577
exitFunc(0)
2678
}

0 commit comments

Comments
 (0)