github.com/kcmvp/gob@v1.0.17/cmd/gbc/artifact/hook.go (about) 1 package artifact 2 3 import ( 4 "bufio" 5 "fmt" 6 "github.com/fatih/color" 7 "github.com/samber/lo" 8 "os" 9 "path/filepath" 10 ) 11 12 const ( 13 command = "gbc" 14 execCfgKey = "exec" 15 //hook script name 16 CommitMsg = "commit-msg" 17 PreCommit = "pre-commit" 18 PrePush = "pre-push" 19 ) 20 21 func HookScripts() map[string]string { 22 return map[string]string{ 23 CommitMsg: fmt.Sprintf("%s exec %s $1", command, CommitMsg), 24 PreCommit: fmt.Sprintf("%s exec %s", command, PreCommit), 25 PrePush: fmt.Sprintf("%s exec %s $1 $2", command, PrePush), 26 } 27 } 28 29 type GitHook struct { 30 CommitMsg string `mapstructure:"commit-msg"` 31 PreCommit []string `mapstructure:"pre-commit"` 32 PrePush []string `mapstructure:"pre-push"` 33 } 34 35 func (project *Project) GitHook() GitHook { 36 var hook GitHook 37 project.load().UnmarshalKey(execCfgKey, &hook) //nolint 38 return hook 39 } 40 41 type Execution struct { 42 CmdKey string 43 Actions []string 44 } 45 46 func (project *Project) Executions() []Execution { 47 values := project.load().Get(execCfgKey) 48 if values == nil { 49 return []Execution{} 50 } 51 return lo.MapToSlice(values.(map[string]any), func(key string, v any) Execution { 52 var actions []string 53 if _, ok := v.(string); ok { 54 actions = append(actions, v.(string)) 55 } else { 56 actions = lo.Map(v.([]any), func(item any, _ int) string { 57 return fmt.Sprintf("%s", item) 58 }) 59 } 60 return Execution{CmdKey: key, Actions: actions} 61 }) 62 } 63 64 // SetupHooks setup git local hooks for project. force means always update gob.yaml 65 func (project *Project) SetupHooks(force bool) error { 66 if force { 67 hook := map[string]any{ 68 fmt.Sprintf("%s.%s", execCfgKey, CommitMsg): "^#[0-9]+:\\s*.{10,}$", 69 fmt.Sprintf("%s.%s", execCfgKey, PreCommit): []string{"lint", "test"}, 70 fmt.Sprintf("%s.%s", execCfgKey, PrePush): []string{"test"}, 71 } 72 if err := project.mergeConfig(hook); err != nil { 73 color.Red("failed to setup hook") 74 } 75 } 76 if !InGit() { 77 color.Yellow("project is not in the source control") 78 return nil 79 } 80 // force load configuration again for testing 81 _ = project.load().ReadInConfig() 82 gitHook := CurProject().GitHook() 83 var hooks []string 84 if len(gitHook.CommitMsg) > 0 { 85 hooks = append(hooks, CommitMsg) 86 } 87 if len(gitHook.PreCommit) > 0 { 88 hooks = append(hooks, PreCommit) 89 } 90 if len(gitHook.PrePush) > 0 { 91 hooks = append(hooks, PrePush) 92 } 93 shell := lo.IfF(Windows(), func() string { 94 return "#!/usr/bin/env bash\n" 95 }).Else("#!/bin/sh\n") 96 hookDir := CurProject().HookDir() 97 for name, script := range HookScripts() { 98 if lo.Contains(hooks, name) || force { 99 msgHook, _ := os.OpenFile(filepath.Join(hookDir, name), os.O_RDWR|os.O_CREATE|os.O_TRUNC, os.ModePerm) 100 writer := bufio.NewWriter(msgHook) 101 writer.WriteString(shell) 102 writer.WriteString("\n") 103 writer.WriteString(script) 104 writer.Flush() 105 msgHook.Close() 106 } else { 107 os.Remove(filepath.Join(hookDir, name)) 108 } 109 } 110 return nil 111 }