Skip to content

Commit ce7ef0e

Browse files
committed
Set path for gtm in git hook
1 parent e5deee3 commit ce7ef0e

4 files changed

Lines changed: 83 additions & 29 deletions

File tree

project/project.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"io/ioutil"
1212
"os"
1313
"path/filepath"
14+
"regexp"
1415
"runtime"
1516
"strings"
1617
"text/template"
@@ -29,8 +30,12 @@ var (
2930

3031
var (
3132
// GitHooks is map of hooks to apply to the git repo
32-
GitHooks = map[string]string{
33-
"post-commit": "gtm commit --yes"}
33+
GitHooks = map[string]scm.GitHook{
34+
"post-commit": {
35+
Exe: "gtm",
36+
Command: "gtm commit --yes",
37+
RE: regexp.MustCompile(`(?s)[/,\\,:,a-z,A-Z,0-9,$,-,_,=,(,),",., ]*gtm(.exe"|)\s+commit\s+--yes\.*`)},
38+
}
3439
// GitConfig is map of git configuration settings
3540
GitConfig = map[string]string{
3641
"alias.pushgtm": "push origin refs/notes/gtm-data",
@@ -51,7 +56,7 @@ const initMsgTpl string = `
5156
{{print "Git Time Metric initialized for " (.ProjectPath) | printf (.HeaderFormat) }}
5257
5358
{{ range $hook, $command := .GitHooks -}}
54-
{{- $hook | printf "%16s" }}: {{ $command }}
59+
{{- $hook | printf "%16s" }}: {{ $command.Command }}
5560
{{ end -}}
5661
{{ range $key, $val := .GitConfig -}}
5762
{{- $key | printf "%16s" }}: {{ $val }}
@@ -66,7 +71,7 @@ const removeMsgTpl string = `
6671
The following items have been removed.
6772
6873
{{ range $hook, $command := .GitHooks -}}
69-
{{- $hook | printf "%16s" }}: {{ $command }}
74+
{{- $hook | printf "%16s" }}: {{ $command.Command }}
7075
{{ end -}}
7176
{{ range $key, $val := .GitConfig -}}
7277
{{- $key | printf "%16s" }}: {{ $val }}
@@ -148,7 +153,7 @@ func Initialize(terminal bool, tags []string, clearTags bool) (string, error) {
148153
Tags string
149154
HeaderFormat string
150155
ProjectPath string
151-
GitHooks map[string]string
156+
GitHooks map[string]scm.GitHook
152157
GitConfig map[string]string
153158
GitIgnore string
154159
Terminal bool
@@ -221,7 +226,7 @@ func Uninitialize() (string, error) {
221226
struct {
222227
HeaderFormat string
223228
ProjectPath string
224-
GitHooks map[string]string
229+
GitHooks map[string]scm.GitHook
225230
GitConfig map[string]string
226231
GitIgnore string
227232
}{

project/project_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ func TestInitialize(t *testing.T) {
6060
if b, err = ioutil.ReadFile(fp); err != nil {
6161
t.Fatalf("Initialize(), want error nil, got %s", err)
6262
}
63-
if !strings.Contains(string(b), command+"\n") {
64-
t.Errorf("Initialize(), want %s got %s", command, string(b))
63+
if !strings.Contains(string(b), command.Command) {
64+
t.Errorf("Initialize(), want %s got %s", command.Command, string(b))
6565
}
6666
}
6767

@@ -109,8 +109,8 @@ func TestInitialize(t *testing.T) {
109109
if b, err = ioutil.ReadFile(fp); err != nil {
110110
t.Fatalf("Initialize(true), want error nil, got %s", err)
111111
}
112-
if !strings.Contains(string(b), command+"\n") {
113-
t.Errorf("Initialize(true), want %s got %s", command, string(b))
112+
if !strings.Contains(string(b), command.Command) {
113+
t.Errorf("Initialize(true), want %s got %s", command.Command, string(b))
114114
}
115115
}
116116

@@ -187,8 +187,8 @@ func TestUninitialize(t *testing.T) {
187187
if b, err = ioutil.ReadFile(fp); err != nil {
188188
t.Fatalf("Uninitialize(), want error nil, got %s", err)
189189
}
190-
if strings.Contains(string(b), command+"\n") {
191-
t.Errorf("Uinitialize(), do not want %s got %s", command, string(b))
190+
if strings.Contains(string(b), command.Command+"\n") {
191+
t.Errorf("Uinitialize(), do not want %s got %s", command.Command, string(b))
192192
}
193193
}
194194

scm/git.go

Lines changed: 53 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ import (
99
"fmt"
1010
"io/ioutil"
1111
"os"
12+
"os/exec"
1213
"path/filepath"
14+
"regexp"
15+
"runtime"
1316
"strings"
1417
"time"
1518

@@ -556,10 +559,44 @@ func ConfigRemove(settings map[string]string, wd ...string) error {
556559
return nil
557560
}
558561

562+
// GitHook is the Command with options to be added/removed from a git hook
563+
// Exe is the executable file name for Linux/MacOS
564+
// RE is the regex to match on for the command
565+
type GitHook struct {
566+
Exe string
567+
Command string
568+
RE *regexp.Regexp
569+
}
570+
571+
func (g GitHook) getCommandPath() string {
572+
// save current dir & change to root
573+
// to guarantee we get the full path
574+
wd, err := os.Getwd()
575+
defer os.Chdir(wd)
576+
os.Chdir(string(filepath.Separator))
577+
578+
p, err := exec.LookPath(g.getExeForOS())
579+
if err != nil {
580+
return g.Command
581+
}
582+
if runtime.GOOS == "windows" {
583+
// put "" around file path
584+
return strings.Replace(g.Command, g.Exe, fmt.Sprintf("\"%s\"", p), 1)
585+
}
586+
return strings.Replace(g.Command, g.Exe, p, 1)
587+
}
588+
589+
func (g GitHook) getExeForOS() string {
590+
if runtime.GOOS == "windows" {
591+
return fmt.Sprintf("gtm.%s", "exe")
592+
}
593+
return g.Exe
594+
}
595+
559596
// SetHooks creates git hooks
560-
func SetHooks(hooks map[string]string, wd ...string) error {
597+
func SetHooks(hooks map[string]GitHook, wd ...string) error {
561598
const shebang = "#!/bin/sh"
562-
for hook, command := range hooks {
599+
for ghfile, hook := range hooks {
563600
var (
564601
p string
565602
err error
@@ -573,7 +610,7 @@ func SetHooks(hooks map[string]string, wd ...string) error {
573610
return err
574611
}
575612
}
576-
fp := filepath.Join(p, ".git", "hooks", hook)
613+
fp := filepath.Join(p, ".git", "hooks", ghfile)
577614
hooksDir := filepath.Join(p, ".git", "hooks")
578615

579616
var output string
@@ -596,8 +633,10 @@ func SetHooks(hooks map[string]string, wd ...string) error {
596633
output = fmt.Sprintf("%s\n%s", shebang, output)
597634
}
598635

599-
if !strings.Contains(output, command) {
600-
output = fmt.Sprintf("%s\n%s\n", output, command)
636+
if hook.RE.MatchString(output) {
637+
output = hook.RE.ReplaceAllString(output, fmt.Sprintf("%s", hook.getCommandPath()))
638+
} else {
639+
output = fmt.Sprintf("%s\n%s", output, hook.getCommandPath())
601640
}
602641

603642
if err = ioutil.WriteFile(fp, []byte(output), 0755); err != nil {
@@ -613,8 +652,8 @@ func SetHooks(hooks map[string]string, wd ...string) error {
613652
}
614653

615654
// RemoveHooks remove matching git hook commands
616-
func RemoveHooks(hooks map[string]string, wd ...string) error {
617-
for hook, command := range hooks {
655+
func RemoveHooks(hooks map[string]GitHook, wd ...string) error {
656+
for ghfile, hook := range hooks {
618657
var (
619658
p string
620659
err error
@@ -628,7 +667,7 @@ func RemoveHooks(hooks map[string]string, wd ...string) error {
628667
return err
629668
}
630669
}
631-
fp := filepath.Join(p, ".git", "hooks", hook)
670+
fp := filepath.Join(p, ".git", "hooks", ghfile)
632671

633672
if _, err := os.Stat(fp); os.IsNotExist(err) {
634673
continue
@@ -640,8 +679,12 @@ func RemoveHooks(hooks map[string]string, wd ...string) error {
640679
}
641680
output := string(b)
642681

643-
if strings.Contains(output, command) {
644-
output = strings.Replace(output, command, "", -1)
682+
if hook.RE.MatchString(output) {
683+
output := hook.RE.ReplaceAllString(output, "")
684+
i := strings.LastIndexAny(output, "\n")
685+
if i > -1 {
686+
output = output[0:i]
687+
}
645688
if err = ioutil.WriteFile(fp, []byte(output), 0755); err != nil {
646689
return err
647690
}

scm/git_test.go

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"io/ioutil"
99
"os"
1010
"path"
11+
"regexp"
1112
"strings"
1213
"testing"
1314

@@ -340,7 +341,12 @@ func TestSetGitHooks(t *testing.T) {
340341
defer repo.Remove()
341342

342343
repoPath := repo.PathIn("")
343-
hooks := map[string]string{"post-commit": "gtm commit --yes"}
344+
hooks := map[string]GitHook{
345+
"post-commit": {
346+
Exe: "gtm",
347+
Command: "gtm commit --yes",
348+
RE: regexp.MustCompile(`(?s)[/,:,a-z,A-Z,0-9,$,-,_,=, ]*gtm\s+commit\s+--yes\.*`)},
349+
}
344350

345351
// test when hook exists
346352
err := ioutil.WriteFile(path.Join(repoPath, ".git", "hooks", "post-commit"), []byte{}, 0755)
@@ -357,8 +363,8 @@ func TestSetGitHooks(t *testing.T) {
357363
t.Fatalf("SetHooks(hooks) expect error nil, got %s", err)
358364
}
359365
output := string(b)
360-
if !strings.Contains(output, hooks["post-commit"]) {
361-
t.Errorf("SetHooks(hooks) expected post-commit to contain %s, got %s", hooks["post-commit"], output)
366+
if !strings.Contains(output, hooks["post-commit"].Command) {
367+
t.Errorf("SetHooks(hooks) expected post-commit to contain %s, got %s", hooks["post-commit"].Command, output)
362368
}
363369

364370
// test if hook doesn't exist
@@ -376,8 +382,8 @@ func TestSetGitHooks(t *testing.T) {
376382
t.Fatalf("SetHooks(hooks) expect error nil, got %s", err)
377383
}
378384
output = string(b)
379-
if !strings.Contains(output, hooks["post-commit"]) {
380-
t.Errorf("SetHooks(hooks) expected post-commit to contain %s, got %s", hooks["post-commit"], output)
385+
if !strings.Contains(output, hooks["post-commit"].Command) {
386+
t.Errorf("SetHooks(hooks) expected post-commit to contain %s, got %s", hooks["post-commit"].Command, output)
381387
}
382388

383389
// test if hooks folder doesn't exist
@@ -395,8 +401,8 @@ func TestSetGitHooks(t *testing.T) {
395401
t.Fatalf("SetHooks(hooks) expect error nil, got %s", err)
396402
}
397403
output = string(b)
398-
if !strings.Contains(output, hooks["post-commit"]) {
399-
t.Errorf("SetHooks(hooks) expected post-commit to contain %s, got %s", hooks["post-commit"], output)
404+
if !strings.Contains(output, hooks["post-commit"].Command) {
405+
t.Errorf("SetHooks(hooks) expected post-commit to contain %s, got %s", hooks["post-commit"].Command, output)
400406
}
401407

402408
}

0 commit comments

Comments
 (0)