Skip to content

Commit cbceb0b

Browse files
feat: custom config in hook, replace hook
1 parent 21bb2fb commit cbceb0b

File tree

5 files changed

+153
-60
lines changed

5 files changed

+153
-60
lines changed

cmd/callback.go

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,20 @@ package cmd
22

33
import (
44
"fmt"
5-
"os"
65

76
"github.com/urfave/cli/v2"
87

98
"github.com/conventionalcommit/commitlint/config"
10-
"github.com/conventionalcommit/commitlint/hook"
119
)
1210

1311
const (
1412
// ErrExitCode represent error exit code
1513
ErrExitCode = 1
16-
17-
// HookDir represent default hook directory
18-
HookDir = ".commitlint/hooks"
1914
)
2015

2116
// Init is the callback function for init command
22-
func Init(isGlobal bool) error {
23-
hookDir, err := getHookDir(isGlobal)
24-
if err != nil {
25-
return err
26-
}
27-
28-
err = os.MkdirAll(hookDir, os.ModePerm)
29-
if err != nil {
30-
return err
31-
}
32-
33-
// create hook file
34-
err = hook.WriteToFile(hookDir)
17+
func Init(confPath string, isGlobal, isReplace bool) error {
18+
hookDir, err := initHooks(confPath, isGlobal, isReplace)
3519
if err != nil {
3620
return err
3721
}
@@ -63,8 +47,8 @@ func Lint(confPath, msgPath string) error {
6347
}
6448

6549
// CreateHook is the callback function for create hook command
66-
func CreateHook() (retErr error) {
67-
return hook.WriteToFile(".")
50+
func CreateHook(confPath string, isReplace bool) error {
51+
return createHooks(confPath, isReplace)
6852
}
6953

7054
// CreateConfig is the callback function for create config command

cmd/cmd.go

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
package cmd
33

44
import (
5+
"fmt"
6+
57
"github.com/urfave/cli/v2"
68
)
79

@@ -40,10 +42,29 @@ func initCmd() *cli.Command {
4042
Aliases: []string{"g"},
4143
Usage: "sets git hook in global config",
4244
},
45+
&cli.StringFlag{
46+
Name: "config",
47+
Aliases: []string{"c", "conf"},
48+
Value: "",
49+
Usage: "optional config file `conf.yaml`",
50+
},
51+
&cli.BoolFlag{
52+
Name: "replace",
53+
Usage: "replace files if already exists",
54+
},
4355
},
4456
Action: func(ctx *cli.Context) error {
57+
confPath := ctx.String("config")
4558
isGlobal := ctx.Bool("global")
46-
return Init(isGlobal)
59+
isReplace := ctx.Bool("replace")
60+
61+
err := Init(confPath, isGlobal, isReplace)
62+
if isHookExists(err) {
63+
fmt.Println("commitlint init failed")
64+
fmt.Println("run with --replace to replace existing files")
65+
return nil
66+
}
67+
return err
4768
},
4869
}
4970
}
@@ -69,8 +90,32 @@ func createCmd() *cli.Command {
6990
hookCmd := &cli.Command{
7091
Name: "hook",
7192
Usage: "creates commit-msg file in current directory",
93+
Flags: []cli.Flag{
94+
&cli.StringFlag{
95+
Name: "config",
96+
Aliases: []string{"c", "conf"},
97+
Value: "",
98+
Usage: "optional config file `conf.yaml`",
99+
},
100+
&cli.BoolFlag{
101+
Name: "replace",
102+
Usage: "replace hook files if already exists",
103+
},
104+
},
72105
Action: func(ctx *cli.Context) error {
73-
return CreateHook()
106+
confPath := ctx.String("config")
107+
isReplace := ctx.Bool("replace")
108+
err := CreateHook(confPath, isReplace)
109+
if err != nil {
110+
if isHookExists(err) {
111+
fmt.Println("create hook failed. files already exists")
112+
fmt.Println("run with --replace to replace existing hook files")
113+
return nil
114+
}
115+
return err
116+
}
117+
fmt.Println("hooks created")
118+
return nil
74119
},
75120
}
76121

cmd/hook.go

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package cmd
2+
3+
import (
4+
"errors"
5+
"os"
6+
"path/filepath"
7+
8+
"github.com/conventionalcommit/commitlint/hook"
9+
)
10+
11+
const (
12+
// hookBaseDir represent default hook directory
13+
hookBaseDir = ".commitlint/hooks"
14+
)
15+
16+
var errHooksExist = errors.New("hooks already exists")
17+
18+
func initHooks(confPath string, isGlobal, isReplace bool) (string, error) {
19+
hookDir, err := getHookDir(hookBaseDir, isGlobal)
20+
if err != nil {
21+
return "", err
22+
}
23+
24+
err = writeHooks(hookDir, confPath, isReplace)
25+
if err != nil {
26+
return "", err
27+
}
28+
return hookDir, nil
29+
}
30+
31+
func createHooks(confPath string, isReplace bool) error {
32+
return writeHooks(hookBaseDir, confPath, isReplace)
33+
}
34+
35+
func writeHooks(hookDir, confPath string, isReplace bool) error {
36+
err := os.MkdirAll(hookDir, os.ModePerm)
37+
if err != nil {
38+
return err
39+
}
40+
41+
// if commit-msg already exists skip creating or overwriting it
42+
if _, err := os.Stat(hookDir); !os.IsNotExist(err) {
43+
if !isReplace {
44+
return errHooksExist
45+
}
46+
}
47+
48+
// create hook file
49+
return hook.WriteHooks(hookDir, confPath)
50+
}
51+
52+
func getHookDir(baseDir string, isGlobal bool) (string, error) {
53+
baseDir = filepath.Clean(baseDir)
54+
55+
if isGlobal {
56+
// get user home dir
57+
homeDir, err := os.UserHomeDir()
58+
if err != nil {
59+
return "", err
60+
}
61+
62+
// create hooks dir
63+
hookDir := filepath.Join(homeDir, baseDir)
64+
return hookDir, nil
65+
}
66+
67+
gitDir, err := getRepoRootDir()
68+
if err != nil {
69+
return "", err
70+
}
71+
return filepath.Join(gitDir, baseDir), nil
72+
}
73+
74+
func isHookExists(err error) bool {
75+
return err == errHooksExist
76+
}

cmd/util.go

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -44,28 +44,6 @@ func readStdInPipe() (string, error) {
4444
return strings.TrimSpace(s), nil
4545
}
4646

47-
func getHookDir(isGlobal bool) (string, error) {
48-
baseDir := filepath.Clean(HookDir)
49-
50-
if isGlobal {
51-
// get user home dir
52-
homeDir, err := os.UserHomeDir()
53-
if err != nil {
54-
return "", err
55-
}
56-
57-
// create hooks dir
58-
hookDir := filepath.Join(homeDir, baseDir)
59-
return hookDir, nil
60-
}
61-
62-
gitDir, err := getRepoRootDir()
63-
if err != nil {
64-
return "", err
65-
}
66-
return filepath.Join(gitDir, baseDir), nil
67-
}
68-
6947
func getRepoRootDir() (string, error) {
7048
byteOut := &bytes.Buffer{}
7149

hook/hook.go

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,18 @@
22
package hook
33

44
import (
5+
"bufio"
6+
"io"
57
"os"
68
"path/filepath"
9+
"strings"
710
)
811

9-
// CommitMsgHook represent commit-msg hook file name
10-
const CommitMsgHook = "commit-msg"
12+
// commitMsgHook represent commit-msg hook file name
13+
const commitMsgHook = "commit-msg"
1114

12-
const hookFile = `#!/bin/sh
13-
14-
commitlint lint --message $1
15-
`
16-
17-
// WriteToFile util func to write commit-msg hook to given file
18-
func WriteToFile(hookDir string) (retErr error) {
19-
hookFilePath := filepath.Join(hookDir, filepath.Clean(CommitMsgHook))
20-
// if commit-msg already exists skip creating or overwriting it
21-
if _, err := os.Stat(hookFilePath); !os.IsNotExist(err) {
22-
return nil
23-
}
15+
func WriteHooks(outDir string, confPath string) (retErr error) {
16+
hookFilePath := filepath.Join(outDir, commitMsgHook)
2417
// commit-msg needs to be executable
2518
file, err := os.OpenFile(hookFilePath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0700)
2619
if err != nil {
@@ -32,7 +25,24 @@ func WriteToFile(hookDir string) (retErr error) {
3225
retErr = err1
3326
}
3427
}()
28+
return writeTo(file, confPath)
29+
}
30+
31+
// writeTo util func to write commit-msg hook to given io.Writer
32+
func writeTo(wr io.Writer, confPath string) error {
33+
w := bufio.NewWriter(wr)
34+
35+
w.WriteString("#!/bin/sh")
36+
w.WriteString("\n\ncommitlint lint")
37+
38+
confPath = strings.TrimSpace(confPath)
39+
if confPath != "" {
40+
confPath = filepath.Clean(confPath)
41+
w.WriteString(` --config "` + confPath + `"`)
42+
}
43+
44+
w.WriteString(" --message $1")
45+
w.WriteString("\n")
3546

36-
_, err = file.WriteString(hookFile)
37-
return err
47+
return w.Flush()
3848
}

0 commit comments

Comments
 (0)