-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathset_template.go
More file actions
122 lines (103 loc) · 2.88 KB
/
set_template.go
File metadata and controls
122 lines (103 loc) · 2.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package main
import (
"bufio"
"os"
"os/exec"
"regexp"
"strings"
"text/template"
"github.com/kelseyhightower/envconfig"
"github.com/urfave/cli/v2"
)
const (
dryRunFlag = "dry-run"
issueRefFlag = "issue"
coAuthorFlag = "pair"
)
type Config struct {
AuthorFile string `split_words:"true" default:"$HOME/.git-commit-template-authors"`
IssuePrefix string `split_words:"true" default:"#"`
Template string `split_words:"true" default:"Subject{{if .Issue}}\n\nAddresses: {{.Issue}}{{end}}{{if .CoAuthors}}\n{{end}}{{range .CoAuthors}}\nCo-authored-by: {{.}}{{end}}"`
}
func issueRef(s string, prefix string) string {
if strings.HasPrefix(s, prefix) || len(s) == 0 {
return s
}
return prefix + s
}
func findCoAuthors(s []string, path string) []string {
if fileName, found := strings.CutPrefix(path, "$HOME/"); found {
home, _ := os.UserHomeDir()
path = home + "/" + fileName
}
f, _ := os.Open(path)
defer f.Close()
var coAuthors []string
for _, author := range s {
coAuthor := findCoAuthor(author, f)
if len(coAuthor) > 0 {
coAuthors = append(coAuthors, coAuthor)
}
}
return coAuthors
}
func findCoAuthor(s string, f *os.File) string {
if len(s) == 0 {
return s
}
if match, _ := regexp.MatchString("^.+ <.+@.+>$", s); match {
return s
}
if f == nil {
return ""
}
scanner := bufio.NewScanner(f)
for scanner.Scan() {
if strings.Contains(strings.ToLower(scanner.Text()), strings.ToLower(s)) {
return scanner.Text()
}
}
return ""
}
var SetTemplateCommand = &cli.Command{
Name: "set",
Usage: "Set up template for commit message",
Flags: []cli.Flag{
&cli.BoolFlag{Name: dryRunFlag, Aliases: []string{"d"}, Usage: "Print template to stdout", Value: false},
&cli.StringFlag{Name: issueRefFlag, Aliases: []string{"i"}, Usage: "Issue reference to add to template", Value: ""},
&cli.StringSliceFlag{Name: coAuthorFlag, Aliases: []string{"p"}, Usage: "Co-author(s) to add to template", Value: cli.NewStringSlice()},
},
Before: GitCheck,
Action: func(c *cli.Context) error {
var cfg Config
err := envconfig.Process("GIT_COMMIT_TEMPLATE", &cfg)
if err != nil {
return cli.Exit("Reading environment variables failed", 1)
}
var f *os.File
if c.Bool(dryRunFlag) {
f = os.Stdout
} else {
var err error
f, err = os.Create(".git/.gitmessage.txt")
if err != nil {
return cli.Exit("Saving template file failed", 1)
}
defer f.Close()
}
var message = template.Must(
template.New("message").Parse(cfg.Template),
)
_ = message.Execute(f, struct {
Issue string
CoAuthors []string
}{issueRef(c.String(issueRefFlag), cfg.IssuePrefix), findCoAuthors(c.StringSlice(coAuthorFlag), cfg.AuthorFile)})
if !c.Bool(dryRunFlag) {
err := exec.Command("git", "config", "--local", "commit.template", ".git/.gitmessage.txt").Run()
if err != nil {
return cli.Exit("Updating Git config failed", 1)
}
}
return nil
},
}